说明
与顺序表相比,允许存储空间不连续,插入删除时不需要移动大量的元素,只需修改指针即可,但查找某个元素,只能从头遍历整个链表。
插入
删除
代码
/*
** slink create by yubo.wang 2018.9.12
*/
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *next;
}SLink;
SLink *MaxNode(SLink *L);
void InitList(SLink *&L) /*SLink *&L作为引用型参数或者用二级指针SLink **L*/
{
L=(SLink *)malloc(sizeof(SLink));
L->next = NULL;
}
int GetLength(SLink *L)
{
int i=0;
SLink *p=L->next;
while(p != NULL)
{
i++;
p=p->next;
}
return i;
}
int GetElem(SLink *L,int i,ElemType &e)
{
int j=1;
SLink *p=L->next;
if(i<1 || i>GetLength(L))
return 0;
while(j<i)
{
p=p->next;
j++;
}
e=p->data;
return 1;
}
int Locate(SLink *L,ElemType x)
{
int i=1;
SLink *p=L->next;
while(p!=NULL && p->data!=x)
{
p=p->next;
i++;
}
if(NULL == p)
return 0;
else
return i;
}
int InsElem(SLink *L,ElemType x,int i)//初始化是尾插,也可中途插入
{
int j=1;
SLink *p=L,*s;
s=(SLink *)malloc(sizeof(SLink));
s->data=x;
s->next=NULL;
if(i<1 || i>GetLength(L)+1)//防止i越界
return 0;
while(j<i)
{
p=p->next;
j++;
}
s->next = p->next;
p->next = s;
return 1;
}
int DelElem(SLink *L,int i)
{
int j=1;
SLink *p=L,*q;
if(i<1 || i>GetLength(L))
return 0;
while(j<i)
{
p=p->next;
j++;
}
q=p->next;
printf("%c\n", q->data);
p->next=q->next;
free(q);
return 1;
}
void DispList(SLink *L)
{
SLink *p=L->next;
while(p != NULL)
{
printf("%c ", p->data);
p=p->next;
}
printf("\n");
}
int main()
{
int i;
ElemType e;
SLink *L=NULL;
InitList(L);//initial head
InsElem(L,'a',1);
InsElem(L,'b',2);
InsElem(L,'c',3);
InsElem(L,'d',4);
InsElem(L,'e',5);
InsElem(L,'f',6);
printf("List:");
DispList(L);
printf("Length: %d\n", GetLength(L));
i=3;
GetElem(L,i,e);
printf("index %d data is:%c\n", i,e);
e='e';
printf("data %c index is: %d\n", e,Locate(L,e));
i=4;
printf("delete index %d data ", i);
DelElem(L,i);
i=2;
e='w';
printf("insert index %d data %c\n", i, e);
InsElem(L,e,2);
printf("List:");
DispList(L);
printf("MaxNode:%c\n", MaxNode(L)->data);
}
/*通过一趟遍历返回单链表元素最大值的结点*/
SLink *MaxNode(SLink *L)
{
SLink *p=L->next,*q=p;//p用来遍历,q用来记录最大的值结点
while(p != NULL)
{
if(p->data > q->data)
q=p;
p=p->next;
}
return q;
}
/*A B两个带头结点的非递减单链表归并为一个非递增的有序单链表,不占用额外空间*/
SLink *connect(SLink *ha,SLink *hb)
{
SLink *pa=ha->next,*pb=hb->next,*hc,*tc;
hc=pa;
hc->next=NULL;
tc=hc;//tc始终指向hc的最后一个结点
while(pa!=NULL && pb!=NULL)
{
if(pa->data < pb->data)//将pa链接到tc之后
{
tc->next=pa;
tc=pa;
pa=pa->next;
}
else if(pa->data > pb->data)//将pb链接到tc之后
{
tc->next=pb;
tc=pb;
pb=pb->next;
}
else//将pa pb链接到tc之后
{
tc->next=pa;
tc=pa;
pa=pa->next;
tc->next=pb;
tc=pb;
pb=pb->next;
}
}
tc->next=NULL;
if(pa != NULL)//ha链表还有结点时
tc->next=pa;
if(pb != NULL)//hb链表还有结点时
tc->next=pb;
return hc;
}
int Reverse(SLink *L)//链表倒置
{
SLink *p,*q,*r;
p=L;
q=p->next;
while(q != NULL)
{
r=q->next;
q->next=p;
p=q;
q=r;
}
L->next=p;//待确定
}
int DelElemAll(SLink *L)//删除所有节点
{
SLink *p;
p=L;
while(p!=NULL)
{
p=p->next;
free(L);
L=p;
}
}