链表,一种线性表,但并不会按线性的顺序存储数据。而是在每个节点里存到下一个节点的指针(Pointer)。因为没必要须按顺序存储,链表在插入的时候能够达到O(1)的复杂度,比另外一种线性表顺序表快得多,可是查找一个节点或者访问特定编号的节点则须要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。函数
结点类型描述指针
typedef struct LinkList{ ElemType data; //数据域 struct Node *next; //指针域 }Node, *LinkList;
初始化code
LinkList initList() { LinkList L = (LinkList)malloc(sizeof(Node)); L->next = NULL; return L; }
头插法input
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; }
尾插法it
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; }
查找List
//按序号查找结点值,取出链表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个位置next
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; }