重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
1.使用链表时候,先确认要使用的是单向链表,还是双向链表,或者是循环链表。一定要初始化。
公司主营业务:网站建设、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联公司推出召陵免费做网站回馈大家。
2.添加节点时候,要注意是否队列已满。
3.删除节点的时候,要注意队列是否为空。
4.要有可以判断链表是否为空的函数。
5.要有可以判断链表节点个数的函数。
const int NULL =0;
template class T
struct Node
{
T data; //数据域
struct Node T * next; //指针域,在这里T可省略
};
template class T
class LinkList
{
public:
LinkList(){first = new Node T; first-next = NULL;}//无参构造函数
LinkList(T a [], int n);//有参构造函数,使用含有n个元素的数组a初始化单链表
~LinkList(); //析构函数
int GetLength(); //获取线性表的长度
Node T * Get(int i); //获取线性表第i个位置上的元素结点地址
int Locate (T x); //查找线性表中值为x的元素,找到后返回其位置
void Insert (int i, T x);//在线性表的第i个位置上插入值为x的新元素
T Delete(int i); //删除线性表第i个元素,并将该元素返回
void PrintList(); //按次序遍历线性表中的各个数据元素
Node T * GetFirst(){return first;}
private:
Node T * first; //头指针
};
#include "linklist.h"
#include "iostream"
using namespace std;
/*
template class T
LinkListT::LinkList(T a [], int n) //头插法建立单链表
{
first = new Node T;
first -next = NULL; //构造空单链表
for (int i=n-1;i=0;i--)
{
Node T * s = new Node T;//①建立新结点
s-data = a[i]; //②将a[i]写入到新结点的数据域
s-next = first-next; //③修改新结点的指针域
first-next = s; //④修改头结点的指针域,将新结点加入到链表中
}
}
*/
template class T
LinkListT::LinkList(T a [], int n) //尾插法建立单链表
/*
① 在堆中建立新结点:Node T * s = new Node T;
② 将a[i]写入到新结点的数据域:s-data = a[i];
③ 将新结点加入到链表中: r-next = s;
④ 修改尾指针:r = s;
*/
{
first = new Node T;
Node T * r = first;
for (int i=0;in;i++)
{
Node T * s = new Node T;//①建立新结点
s-data = a[i]; //②将a[i]写入到新结点的数据域
r-next = s; //③将新结点加入到链表中
r = s; //④修改尾指针
}
r-next = NULL; //终端结点的指针域设为空
}
template class T
LinkListT::~LinkList() //析构函数
{
Node T * p = first; //初始化工作指针p
while (p) //要释放的结点存在
{
first = p; //暂存要释放的结点
p = p - next; //移动工作指针
delete first; //释放结点
}
}
template class T
Node T * LinkListT::Get(int i) //获取线性表第i个位置上的元素
{
Node T * p = first - next; //初始化工作指针
int j = 1; //初始化计数器
while ( p j != i ) //两个条件都满足,则继续循环
{
p = p - next; //工作指针后移
j++;
}
if (!p) throw "查找位置非法"; //工作指针已经为空
else return p; //查找到第i个元素
}
template class T
int LinkListT::Locate (T x) //查找线性表中值为x的元素,找到后返回其位置
{
Node T * p = first -next; //初始化工作指针
int j=1;
while (p)
{
if (p-data == x) return j; //找到被查元素,返回位置
p = p-next;
j++;
}
return -1; //若找不到,返回错误标识-1
}
template class T
void LinkListT::Insert (int i, T x)//在线性表的第i个位置上插入值为x的新元素
{
Node T * p = first; //初始化工作指针
if (i != 1) p = Get(i-1); //若不是在第一个位置插入,得到第i-1个元素的地址。
Node T * s = new Node T;//建立新结点
s-data = x;
s-next = p-next;
p-next = s; //将新结点插入到p所指结点的后面
}
template class T
T LinkListT::Delete(int i) //删除线性表第i个元素,并将该元素返回
{
Node T * p = first; //初始化工作指针
if (i != 1) p = Get(i-1); //若不是在第一个位置插入,得到第i-1个元素的地址。
Node T * q = p-next;
p-next = q-next;
T x = q-data;
delete q;
return x;
}
template class T
void LinkListT::PrintList() //按次序遍历线性表中的各个数据元素
{
Node T * p = first-next ; //初始化工作指针
while (p){
cout p-data endl;
p = p- next;
}
}
LinkList
*q=L,*p;
//这里,你的p没有赋值,当然p=p-next会出错了!!
程序写对了的话,按你的情况是可以去掉那个的
修改:
LinkList
*q,*p=L;
运行结果如下:
完整代码如下:
#includestdio.h
#includestdlib.h
typedef struct LNode
{
char data;
LNode *next;
}* LNodePtr;
LNodePtr CreateList()
{
//初始化头节点
LNodePtr head = (LNodePtr)malloc(sizeof(LNode));
head-data = 0;
head-next = NULL;
LNodePtr tNode;//临时节点
char data;
while(true)
{
scanf("%c",data);
if(data == '\0' || data == '\n' || data == '\r' || data == '\t')
{
continue;
}
if(data == '!')//输入感叹号停止插入节点
{
printf("输入链表元素结束。\n");
break;
}
if(data = 'A' data = 'Z')
{
tNode = (LNodePtr)malloc(sizeof(LNode));
tNode-data = data; /* 数据域赋值 */
tNode-next = head-next;
head-next = tNode;
}
else
{
printf("输入字符需为大写字母。\n");
}
}
return head;
}
/**
加密函数,加密的方式为链接head的所有节点前移offset位,但是不支持offset比链表的节点数多
@param head 链表头节点
@param offset 节点前移的位数
*/
void EncryptList(LNodePtr head,int offset)
{
LNodePtr tNode = head-next;
int i;
for(i = 0; i offset; i++)
{
if(tNode-next != NULL)
{
tNode = tNode-next;
}
}
if(i == offset)
{
LNodePtr newHead = tNode;
LNodePtr tail = tNode;
while (tail-next != NULL)
{
tail = tail-next;
}
tail-next = head-next;
while(tNode-next != NULL)
{
if(tNode-next != newHead)
{
tNode = tNode-next;
}
else
{
tNode-next = NULL;
break;
}
}
head-next = newHead;
}
else
{
printf("不支持移动");
}
}
void ListPrint(LNodePtr head)
{
if(head-next != NULL)
{
LNodePtr tNode = head-next;
while (tNode-next != NULL)
{
printf("%c ",tNode-data);
tNode = tNode-next;
}
printf("%c",tNode-data);
}
}
int main()
{
LNodePtr list = CreateList();
printf("\n创建的链表如下:\n");
ListPrint(list);
EncryptList(list,3);
printf("\n所有节点前移了3位之后的链表如下:\n");
ListPrint(list);
printf("\n");
return 0;
}
如果看不懂代码可以问我
-运算是间接寻址,你用多指针的话会发现指针用-这种调用方式更简洁
链表指针是C语言的一个难点,但也是重点,学懂了非常有用。要仔细讲就必须先讲变量、指针。
什么是变量?所谓变量,不要浅显的认为会变得量就是变量。举个例子:“教室变不变?”变,因为每天有不同的人在里面上课,但又不变,因为教室始终在那,没有变大或变小。这就是变量:有一个不变的地址和一块可变的存储空间。正常情况下,我们只看到变量这个房间里面的东西,也就是其内容,但不会关注变量的地址,但是C语言的指针,就是这个房间的地址。我们声明变量就相当于盖了间房子存放东西,我们可以直接观看房子里的东西,而声明指针,就是相当于获得了一个定位器,当用指针指向某个变量时,就是用指针给变量定位,以后我们就可以用指针找到他所“跟踪”的变量并可以获得里面的内容。
至于我们写代码的结构体就相当于是有好几个房子组成的别墅,几个房子绑定在一起使用。假设现在有很多这种别墅分布在一个大迷宫里,每间别墅里都有一间房子。里面放了另一个别墅的位置信息,现在你手拿定位器找到了第一栋别墅,从里面得到了你想要的东西(链表的数据部分),然后把下一栋别墅的位置计入你的定位器(p
=
p-next),再走向下一栋别墅……如此走下去,知道走到某地下一栋别墅信息没有了(p-next
==
NULL),你的旅行结束。这就是链表一次遍历的过程。
aTdPage[ucTdPageIndex]-OnInit
();就相当于一个定位器
#includestdio.h
#includewindows.h
#include stdio.h
#include malloc.h
#include stdlib.h
//定义数据类型名称
typedef int DataType;
#define flag -1 //定义数据输入结束的标志数据
//单链表结点存储结构定义
typedef struct Node
{
DataType data;
struct Node *next;
}LNode ,*LinkList;
//建立单链表子函数
LNode *Create_LinkList()
{
LNode *s,*head,*L;int i=0,x; //定义指向当前插入元素的指针
while(1)
{
scanf("%d",x);
if(-1==x)
{ return head;
break;}
s= (LNode *)malloc(sizeof(LNode)); //为当前插入元素的指针分配地址空间
s-data =x;
s-next =NULL;
i++;
if(i==1)
head=s;
else
L-next =s;
L=s;
}
}
//查找子函数(按序号查找)
LNode *Get_LinkList(LinkList L,int i)
{
LNode *p;
int j; //j是计数器,用来判断当前的结点是否是第i个结点
p=L;
j=1;
while(p!=NULLji)
{
p=p-next ; //当前结点p不是第i个且p非空,则p移向下一个结点
j++;
}
return p;
}
//插入运算子函数
void Insert_LinkList(LinkList L,int i,DataType x) //在单链表L中第i个位置插入值为x的新结点
{
LNode *p,*s;
p =Get_LinkList(L,i); //寻找链表的第i-1个位置结点
if(p==NULL)
{
printf("插入位置不合法!");
exit(-1);
}
else
{
s= (LinkList)malloc(sizeof(LNode)); //为当前插入元素的指针分配地址空间
s-data =x;
s-next =p-next ;
p-next =s;
}
}
//单链表的删除运算子函数
void Delete_LinkList(LinkList L,int i) //删除单链表上的第i个结点
{
LNode *p,*q;
p=Get_LinkList(L,i-1); //寻找链表的第i-1个位置结点
if(p==NULL)
{
printf("删除的位置不合法!"); //第i个结点的前驱结点不存在,不能执行删除操作
exit(-1);
}
else
{
if(p-next ==NULL)
{
printf("删除的位置不合法!"); //第i个结点不存在,不能执行删除操作
exit(-1);
}
else
{
q=p-next ;
p-next =p-next-next;
free(q);
}
}
}
//求表长运算子函数
int Length_LinkList(LinkList L)
{
int l; //l记录L的表长
LNode *p;
p=L;
l=1;
while(p-next)
{
p=p-next;
l++;
}
return l;
}
int main ()
{
LNode *head,*p;
head=(LinkList)malloc(sizeof(LNode));
int x,y;
a:
printf("*******menu*******\n");
printf("**创建**********1*\n");
printf("**插入**********2*\n");
printf("**删除**********3*\n");
printf("**表长**********4*\n");
printf("**清屏**********5*\n");
printf("**打印**********6*\n");
printf("**退出******other*\n");
printf("******************\n");
int i=1;
while(i)
{
printf("请输入选项:");
scanf("%d",i);
switch(i)
{
case 1:head=Create_LinkList(); getchar();break;
case 2:printf("请输入位置和数据;");
scanf("%d%d",x,y);
Insert_LinkList(head,x,y);break;
case 3:printf("请输入位置;");
scanf("%d",x);
Delete_LinkList(head,x);break;
case 4:printf("%d",Length_LinkList(head));break;
case 5:system("cls");goto a;
case 6:p=head;
while(p!=NULL)
{printf("%d\n",p-data);
p=p-next;}
break;
default :i=0;
}
}
}
我把创建给改了一下