線性表(Linear List)是由n(n≥0)個數據元素(結點)a[0],a[1],a[2]…,a[n-1]組成的有限序列spa
其中:指針
數據元素的個數n定義爲表的長度 = "list".length() ("list".length() = 0(表裏沒有一個元素)時稱爲空表)code
將非空的線性表(n>=0)記做:(a[0],a[1],a[2],…,a[n-1])排序
數據元素a[i](0≤i≤n-1)只是個抽象符號,其具體含義在不一樣狀況下能夠不一樣 內存
線性鏈表:線性表的鏈式存儲結構的特色是用一組任意的存儲單元存儲線性表的數據元素(這些存儲單元能夠是連續的,也能夠是不連續的)。所以,爲了表示每一個數據元素ai來講,除了存儲其自己的信息以外,還須要存儲一個指示其直接後繼的信息(即直接後繼的存儲位置)。it
節點,包括兩個域:數據域,指針域。鏈表有不少種不一樣的類型:單向鏈表,雙向鏈表以及循環鏈表。io
頭指針:單鏈表的頭指針指向頭結點。List
頭結點:有時,咱們在單鏈表的第一個節點以前附設一個節點,稱之爲頭結點。循環
頭結點的指針域存儲指向第一個節點的指針。若線性表爲空,則頭節點的指針域爲空。im
如圖所示
單鏈表的結構體定義
typedef struct Node { ElemType data; //數據域 struct Node *next; //指針域 }Node,*LinkList;
單鏈表的C實現:
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define SWAP(x,y) {t=x,x=y,y=t;} typedef int ElemType; typedef int Status; typedef struct LNode //線性表的單鏈表存儲結構 { int data; //數據域 struct LNode *next; //指針域 }LNode,*LinkList; //這裏的LNode實際上就是struct LNode的別名,同時LinkList是指針類型的,指向LNode //箭頭運算符是二院操做符,其左邊操做數必須是指針類型 Status Create_LinkList_Head(LinkList *L,int n) { int i; LinkList p; *L=(LinkList)malloc(sizeof(LNode)); (*L)->next=NULL; //先創建一個帶有頭結點的單鏈表 for(i=0 ; i<n ; i++) { if(!(p=(LinkList)malloc(sizeof(LNode)))) { printf("內存分配失敗!"); exit(OVERFLOW); } printf("%d\n",p->data); printf("%x\n",p->data); scanf("%d",&(p->data)); printf("插入數據成功\n"); ////插入到表頭。能夠畫圖演示連接的過程 p->next=(*L)->next; //斷開頭結點和第一個節點間的鏈接。把當前第一個節點的地址賦給新節點的指針域。 (*L)->next=p;//同時頭結點的指針域指向新節點 } printf("ok"); return OK; } Status Create_LinkList_Tail(LinkList *L,int n) { LinkList r,s; *L=(LinkList)malloc(sizeof(LNode)); //新建一個節點 r=*L; int i; for(i=0 ; i<n ; i++) { if(!(s=(LinkList)malloc(sizeof(LNode)))) { printf("內存分配失敗"); exit(OVERFLOW); } scanf("%d",&(s->data)); r->next=s; //新的節點s被連接到上一個節點的指針域 r=s; //把節點s插入到尾部 } r->next=NULL; //當前鏈表結束 return OK; } Status Insert_LinkList(LinkList L,int i,ElemType e)//插入節點 { int j=0; LinkList p=L,s; while(j<i-1 && p) { p=p->next; j++; } if(!p || j>i-1) return ERROR; if(!(s=(LinkList)malloc(sizeof(LNode)))) { printf("內存分配失敗"); exit(OVERFLOW); } s->data=e; s->next=p->next; p->next=s; return OK; } Status Delete_LinkList(LinkList L,int i,ElemType *e)//刪除節點 { int j=0; LinkList p=L->next,q; while(j<i-1 && p) { p=p->next; j++; } if(!p || j>i-1) return ERROR; q=p->next; *e=q->data; p->next=q->next; free(q); return OK; } Status GetElem_LinkList(LinkList L,int i,ElemType *e)//獲得指定的節點元素 { int j; LinkList p; j=1,p=L->next; while(j<i && p) { p=p->next; j++; } if(!p || j>i) return ERROR; *e=p->data; return OK; } Status Print_LinkList(LinkList L)//打印鏈表 { LinkList p=L->next; while(p) { printf("%d ",p->data); p=p->next; } printf("\n"); return OK; } int LinkList_Length(LinkList L)//獲取鏈表的長度 { int len=0; LinkList p=L->next; while(p) { len++; p=p->next; } printf("length ok"); return len; } Status Destory_LinkList(LinkList head)//銷燬鏈表 { LinkList p = head; while(head!=NULL) { head = head->next; free(p); p = head; } return OK; } Status Sort_LinkList(LinkList L)//排序 { LinkList La,Lb; ElemType t; La=L->next; Lb=La->next; while(Lb) { if(La->data>Lb->data) { SWAP(La->data,Lb->data); } Lb = Lb->next; if(!Lb) { La = La->next; Lb = La->next; } } return OK; } int main() { int n,ch,pos; ElemType insert; LinkList L=NULL; printf("請輸入你要輸入元素的個數\n"); scanf("%d",&n); printf("輸入1,選擇頭插法(順序),輸入2,選擇尾插法(逆序)\n"); scanf("%d",&ch); if(ch!=1 && ch!=2) { printf("輸入錯誤,請從新輸入"); scanf("%d",&ch); } if(ch==1) { printf("請輸入%d個元素\n",n); Create_LinkList_Head(&L,n); } else if(ch==2) { printf("請輸入%d個元素\n",n); Create_LinkList_Tail(&L,n); } printf("lyx"); printf("鏈表的長度爲%d\n",LinkList_Length(L)); printf("打印鏈表==>\n"); Print_LinkList(L); printf("請輸入你要插入的數據和位置\n"); scanf("%d%d",&insert,&pos); Insert_LinkList(L,pos,insert); int dl; printf("刪除鏈表中的元素\n"); Delete_LinkList(L,3,&dl); Print_LinkList(L); int e; GetElem_LinkList(L,3,&e); printf("第三個節點的數據域是%d\n",e); printf("鏈表排序\n"); Sort_LinkList(L); Print_LinkList(L); printf("銷燬鏈表\n"); Destory_LinkList(L); return 0; }
====END====