单链表的基本运算
1.单链表的定义
链表是通过一组地址任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的,也可以是不连续的。
链表是线性结构 每个元素有且仅有一个直接前驱和2直接后驱(a1只有后驱,an只有前驱)
单链表结点结构
| data | next |
单链表一般都有头指针head,只要知道了头指针,就可以找到链表的所有结点。
通常为了方便实现链表的各种运算,在单链表的第一个节点之前附设一个类型相同的结点,该结点成为头节点
2.单链表的基本运算
2.1单链表的结构类型定义
`typedef int elemtype //定义结点的数据类型
typedef struct node //定义单链表结点
{
elemtype data;
sruct node *next;
}LinkList;
LinkList *head; //定义头指针
2.2单链表的基本运算
单链表的基本运算包括:链表的建立,求表长,查找,插入,删除,遍历,及置空表等。
2.21单链表的建立
(1)头插法
算法的基本思想是:首先生成一个新结点,将读入的数据存入新结点数据域,然后将新结点x作为第一个结点插入到链表的头结点之后,重复,直到输入结束。
LinkList *Create_LinkList()
{
elemtype ix; //结点的值
Linklist *head,*p; //定义头节点和结点p
head=(LinkList *)malloc(sizeof(LinkList);
if(head==NULL)
return head;
head->next=NULL;//将头指针初始化
printf("请输入数据直到输入0结束\n");
scanf("%d",&x);
while(x!=0)
{
p=(LinkList *)mallo(sizeof(LinkList));
if(p==NUll) //p结点申请失败
return head;
p->data=x; //为p结点数据域赋值
p->next=head->next;//将p指向head的下一个指针
head->next=p;//将新结点p连接在头结点之后
scanf("%d",&x);
}
return head;
}
头插法就是将新生成的元素放在头结点之后,所以后面输入的数据会放在前面。
(2)尾插法
基本思想:生成一个新结点,将新结点连入到当前链表的尾结点之后,重复。
LinkList * Create_LinkListR()
{
elemtype x;
LinkList *head,*p,*tail;
head=(LinkList*) malloc(sizeof(LinkList));
if(head==NULL)
return head;
head->next=NULL;//将头指针初始化
printf("请输入数据直到输入0结束\n");
scanf("%d",&x);
while(x!=0)
{
p=(LinkList *)mallo(sizeof(LinkList));
if(p==NUll) //p结点申请失败
return head;
p->data=x; //为新结点数据域赋值
tail->next=p;//将新结点接在tail指针之后
tail->p; //将tail指针移到新结点
tail->next=NULL; //将tail指针初始化
scanf("%d",&ix);
}
return head;
}
两个算法的时间复杂度都为O(n)
2.3单链表的遍历
基本思想:设一个移动指针,从首结点开始依次访问链表中的每个结点,同时输出数据,直到尾结点
int Print_LinkList(LinkList *head)
{ LinkList *p=head->next;
if(p) //链表为空,返回值为零
return 0;
while(!p)
{
printf("%d",p->data);//输出当前结点的数据
p=p->next; //移动指针到下一个结点
}
return 1;
}
2.4求单链表的长度
基本思想:设置一个移动指针和计数器,从首结点开始扫描到尾结点,每扫描到一个结点,计算器加1,直到结束。
int LinkList_Length(LinkList *head)
{ LinkList *p=head;
int j=0;
if(p-next!=NULL) //只需要看下一个结点存不存在,存在时移动指针才能往下一移动,计数器才能加1
{ p=p->next;
j++;
}
return j;
}
2.5单链表的查找
链表相邻的结点并未存储在物理相邻的存储单元里,不能像顺序表那样直接查找,只能从头指针开始,沿着链一直查找。
(1)按序号查找
和求长度大同小异,设置计数器和移动指针
同时要考虑序号是否有效
LinkList *GetData_LinkList(LinkList *head,int i)
{ LinkList *p;
int j=0;
if(i<1)
return NULL;
p=head;
while(p->next!=NULL&&j<i) //链表遍历完或者没有找到这个序号的时候退出循环
{ p=p->next;
j++;
}
if(i==j) return p;
else return NULL;
(2)按值查找
基本思想:将每个结点与指定关键字中的值进行比较。
LinkList *Search_LinkList(LinkList*head,elemtype key)
{ LinkList *p;
p=head->next;
while(!p)
{
if(p->next!=key)
p=p->next;
else break;
}
return p;
}