链表,一种线性表,但并不会按线性的顺序存储数据。而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。
单链表
结点类型描述
typedef struct LinkList{
ElemType data; //数据域
struct Node *next; //指针域
}Node, *LinkList;
初始化
LinkList initList()
{
LinkList L = (LinkList)malloc(sizeof(Node));
L->next = NULL;
return L;
}
头插法
LinkList List_headInsert(LinkList L)
{
Node *s;
int x;
printf("input the Node number:\n");
scanf("%d",&x);
while(x!=9999) //输入9999时结束
{
s = (Node*)malloc(sizeof(Node));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d",&x);
}
return L;
}
尾插法
LinkList List_TailInsert(LinkList L)
{
int x;
Node *s;
Node *r = L;
printf("input the Node number:\n");
scanf("%d",&x);
while(x!=9999)
{
s = (Node*)malloc(sizeof(Node));
s->data = x;
r->next = s;
r = s; //指向新的表尾结点
scanf("%d",&x);
}
r->next = NULL;
return L;
}
查找
//按序号查找结点值,取出链表L中第i个位置结点
Node *GetElem(LinkList L,int i)
{
int num = 1;
Node *p = L->next;
if(i==0)
return L;
if(i<1)
return NULL;
while(p && num<i)
{
p = p->next;
num++;
}
return p;
}
//按值查找结点
Node *LocateElem(LinkList L,ElemType e)
{
Node *p = L->next;
while(p!=NULL && p-data!=e)
{
p = p->next;
}
return p;
}
插入
将值为e的新结点插入到单链表的第i个位置
LinkList NodeInsert(LinkList L,int i,ElemType e)
{
Node *p = L;
int num = 0;
Node *s = (Node*)malloc(sizeof(Node));
//这里也可以直接调用前面的GetElem函数
//p = GetElem(L,i-1);
while(p && num<i-1)
{
p = p->next;
num++;
}
s->data = e;
s->next = p->next;
p->next = s;
return L;
}
删除
将某个给定的结点删除,按照序号删除,或者按照值删除,下面实现按序号删除
LinkList NodeDelete(LinkList L,i)
{
Node *p;
Node *q;
p = GetElem(L,i-1);
q = p->next;
p->next = p->next->next;
free(q);
return L;
}
求表长
int ListLength(LinkList L)
{
Node *p = L->next;
int i = 0;
while(p)
{
i++;
p = p->next;
}
return i;
}