1. 程式人生 > >靜態連結串列 初始化 插入

靜態連結串列 初始化 插入

 #include <stdio.h>
#include <stdlib.h>

#define OK 1
#define TRUE 1
#define ERROR -1
#define FALSE -1
#define OVERFLOW -2
#define ElemType int
#define Status int
//線性單鏈表 初始化 插入 取出 頭插法 合併升序排列
//-------------------------------線性單鏈表
typedef struct LNode{ //封裝一個線性單鏈表
    ElemType data; //資料域
    struct
LNode *next; //指標域 }LNode, *LinkList;//型別重定義struct LNode為Lnode,型別重定義 Lnode的*指標 為LinkList Status InitList_L(LinkList &L) { //初始化線性連結串列 L = (LinkList)malloc(sizeof(LNode)); //新開闢記憶體,返回指標L L->next = Null;//L->//對於指標p p->a 被定義為 (*p).a (不成文的標準) return TRUE; } Status GetElem_L(LinkList L,int
i,ElemType &e){ //取出元素,i是序號,e為值 //L為帶頭結點的單鏈表的頭指標 //當第i個元素存在時,將值返回給e,返回TRUE, 否則FALSE p = L->next; j = 1;//初始化,p指向第一個結點,j為計數器 while (p && j<i) { //p指標非空,j計數器<i,所以迴圈的終點是i p = p->next; ++j;//指標後移一個,計數器+1一個 } if (!p || j>i) return FALSE;//第i個元素不存在 e = p->data;//取出第i個元素,值為e
return TRUE; }//GetElem_L Status ListInsert_L(LinkList &L, int i, ElemType e) { //在帶head的單鏈表L中第i個位置之前插入元素e p = L; j = 0;//p為指標,被插入的previous Node while (p && j < i - 1) { p = p->next; ++j; }//尋找第i個結點,指標下移,j最後停在i if (!p || j>i) return FALSE; s = (LinkList)malloc(sizeof(LNode));//生成新節點,開闢記憶體空間 返回指標s,insert s->data = e;//s->data域的賦值 assignment s->next = p->next;//指標操作 ,=右往左,指標 指向 p->next = s; } Status ListDelete_L(LinkList &L, int i, ElemType &e) { //在帶head的單鏈表L中第i個位置 刪除元素e p = L; j = 0;//p為指標,被插入的previous Node while (p && j < i - 1) { p = p->next; ++j; }//尋找第i個結點,下標最後是i-1,指標下移,j最後停在i if (p->next || j>i - 1) return FALSE;//刪除位置不合理 q = p->next; //q是被刪除的節點 p->next = q->next;//P的next,指向q->next e = q->data; //取出 值為e free(q);//返回值,釋放空間 } LNode * LocateElem_L(LinkList L, ElemType e) { //在L中找到第一個值和e相同的結點,返回其地址,若不存在,返回空值NULL。 if (!L) return NULL; p = L; while (p&&p->data != e) { p = p->next };//if(!p) p=null; return p;//時間複雜度O(n) } void CreateList_L(LinkList &L, int n) { //頭插法 生成單鏈表 //逆位序輸入n個元素的值,建立帶表頭結點的單鏈線性表L L = (LinkList)malloc(sizeof(LNode)); L->next = NULL;//L->next表示頭結點的指標,先建立一個帶頭結點的單鏈表 for (i = n; i > 0; --i) { p = (LinkList)malloc(sizeof(LNode)); scanf(&p->data);//輸入元素值 p->next = L->next;//挪動 頭指標的後繼 L->next = p;//挪動 頭指標的後繼 } } void MergeList_L(LinkList &La, LinkList &Lb,) { //已知La和Lb升序排列 //合併得到新的單鏈表Lc,Lc的元素也按值非遞減排列 pa = La->next; pb = Lb->next; q = La;//存放臨時指標,q就是pa的前驅元素,q必須始終作為pa的前驅元素 while (pa && pb) { if (pa->data <= pb->data) {//如果小於=,pc指標指向pa q = pa;//q下移 pa = pa->next;//pa下移 } else {//如果>,pc指標指向pb t = pb;// t 下移 pb = pb->next;//pb下移 t->next = pa;//t插入pa的前面 q->next = t; q = t;//q必須始終作為pa的前驅元素,因此t賦值給q }//2個結合起來就是小者排前面,這個程式碼寫的真差,不是人類看的,因為C在A和B只見跳來跳去,臨時pc變數拆成2個就容易理解了 } if (pb) q->next = pb; }//MergeList_L //-------雙向連結串列 Y typedef struct LNode { //封裝 線性單鏈表 ElemType data; //資料域 struct LNode *next; //指標域 } *Link, *Position;//型別重定義struct LNode * 為Link,Link * 為 Position Status MakeNode(Link &p, ElemType e){} void FreeNode(Link &p) typedef struct DuLNode { //封裝 雙向連結串列 ElemType data; struct DuLNode *prior;//前驅 struct DuLNode *next;//後繼 }DuLNode, *DuLinkList; //------靜態連結串列 X 使用陣列實現連結串列,可以在沒有指標的程式語言中實現連結串列結構 #define MAX_SIZE 1000 typedef struct { //封裝 靜態連結串列 ElemType data;//資料 int cur; //遊標(Cursor) } Component, StaticLinkList[MAX_SIZE]; //宣告為StaticLinkList[MAX_SIZE] typedef Component SLinkList[MAX_SIZE]; Status InitList_SL(StaticLinkList &space) { //初始化靜態連結串列 int i; //將一維陣列space中各分量連結成一個備用連結串列,space[0].cur為頭指標。 //“0”表示空指標 for (i = 0; i < MAX_SIZE - 1; i++) space[i].cur = i + 1; //頭遊標和尾遊標 的資料區不存放資料 //頭遊標儲存第一個沒有資料位置的遊標 尾遊標儲存第一個有資料位置的遊標 //最後一個有數值的分量的cursor遊標為0 //未使用的陣列元素成為備用連結串列 //除了頭遊標和尾遊標 每個遊標儲存存放下一個節點的邏輯位置序號 space[MAX_SIZE - 1].cur = 0;//給最後的遊標賦值 return TRUE; } int LocateElem_SL(SLinkList S, ElemType e) { //查詢,返回空閒分量的下標 //在靜態單鏈線性表L中查詢第1個值為e的元素 //若找到,則返回它在L中的依序,否則返回0 i = S[0].cur;//i模擬指標 ,i指示表中第一個結點 while (i && S[i].data != e)//在表中順鏈查詢 i = S[i].cur;//指標下移 return i; } int Malloc_SLL(StaticLinkList space) { //獲取當前空閒量的下標,返回空閒分量的下標,未被使用,用getCur更好理解, i = space[0].cur;//i模擬指標 ,i指示表中第一個結點 if(space[0].cur) //非0,為0就是空連結串列,末尾 space[0].cur = space[i].cur;//指標下移,空閒分量指標下移,0下標的遊標賦值為i下標對應的遊標 return i; } void Free_SLL(SLinkList &space, int k) { //釋放節點 //將下標為k的空閒結點回收到備用連結串列 space[k].cur = space[0].cur; space[0].cur = k; }//Free_SLL Status ListInsert(StaticLinkList L, int i, ElemType e) { int j, k, l;//l是計數器 k = MAX_SIZE - 1;//k表示陣列的最後一個元素 if (i<1 || i>ListLength(L) + 1) { //ListLength為計算連結串列長度的函式 return FALSE; } j = Malloc_SLL(L);//j表示空閒分量的下標,是當前節點下標指標 if (j) { L[j].data = e;//寫入資料 k = L[k].cur;//最後一個元素的遊標指向第一個元素 for (l = 1; l <= i - 1; l++) ////找到第i個位置 { k = L[k].cur;//返回的是第i個下標節點的遊標 } //執行插入後,指標的變化 L[j].cur = L[k].cur; //翻譯成連結串列 j->next = p->next 當前下標節點指標下移 L[k].cur = j;//翻譯成連結串列 p->next = j return TRUE; } return TRUE; }