靜態連結串列的建立以及基本操作
阿新 • • 發佈:2019-01-07
#include <stdio.h> #include <stdlib.h> #define Max 100 typedef int ElemType; /*定義每個節點的資料資訊*/ typedef struct Node { ElemType data;//節點中存放的抽象資料 int next;//記錄下一個節點的位置(位置由下標唯一決定)這裡的next就是下個元素在結構體陣列中的下標 }SLNode; /*靜態連結串列的定義*/ typedef struct Static_List { SLNode store[Max];//靜態的申請了連續的Max個結構體大小的空間 int free_h;//首個空節點的下標,類比如連結串列中的入口地址 }Sqlist; int main() { int Init_Static_List(Sqlist *l); int Creat_Static_List(Sqlist *l); int Length_List(Sqlist l); int Judge_List_Empty(Sqlist l); int Judge_List_Full(Sqlist l); int Insert_List(Sqlist *l); int Research_List(Sqlist l); int Delete_List(Sqlist *l); void Show_List(Sqlist l); Sqlist SL; Init_Static_List(&SL);//靜態連結串列的初始化操作 Creat_Static_List(&SL);//建立靜態連結串列 /*呼叫插入函式,判斷插入位置是否合法,不合法則重新輸入*/ while(-1==Insert_List(&SL)) { printf("The position you insert is illegal!\nPlease input the right position:\n"); Insert_List(&SL); } /*提示連結串列的狀態。為空或者滿或者非空非滿*/ if(0==Judge_List_Empty(SL)) { printf("Current List is empty!\n"); } else { printf("Current List is not empty!\n"); if(1==Judge_List_Full(SL)) printf("Current List is full!\n"); else printf("The length of current list is:%d\n",Length_List(SL)); } /*呼叫資料查詢函式,地址不合法則重新輸入*/ if(-1==Research_List(SL)) { printf("POSITION ERROR\nPlease input the position again\n"); Research_List(SL); } /*呼叫刪除元素函式,地址不合法則重新輸入*/ if(-1==Delete_List(&SL)) { printf("POSITION ERROR\nPlease input the position again\n"); Delete_List(&SL); } /*顯示靜態連結串列的內容*/ Show_List(SL); return 0; } int Init_Static_List(Sqlist *l) { int i; (*l).store[0].next=-1;//(1)靜態的連結串列剛剛建立的時候其頭節點也是尾節點,而尾節點是以其中的next元素為-1定義 (*l).free_h=1;//連結串列剛剛建立的時候,所有的空間都是空的,第一個為空的節點下標為1,free_h賦值為1 for(i=(*l).free_h;i<=Max-2;i++) {(*l).store[i].next=i+1;} (*l).store[Max-1].next=-1;//(1)中的-1表示的是資料元素空間的結尾,而在這裡指的是空閒空間的結尾 printf("The static list initialed success!!!\n"); return 0; } /*建立靜態連結串列(這裡運用的是尾插法)*/ int Creat_Static_List(Sqlist *l) { int n,i,tail=0; printf("Please input the length of the static list:"); scanf("%d",&n); for(i=1;i<=n;i++) { printf("Please input NO.%d's data:",i); scanf("%d",&(*l).store[(*l).free_h].data);/*首先為空閒連結串列的第一個元素賦值,它將被接到原先的表尾*/ /*將(*l).free_h看成一個整體,它代表空閒連結串列的首個元素地址,同時也是空閒連結串列的入口引數*/ (*l).store[tail].next=(*l).free_h;/*將取出的首個元素接到非空閒連結串列的表尾*/ tail=(*l).free_h;/*表尾移動,新插入的元素為新的表尾*/ (*l).free_h=(*l).store[tail].next;/*空閒連結串列的原先的第一個元素被取走了,所以起始元素的地址向下移動一個單位*/ (*l).store[tail].next=-1;/*表尾指向-1,這是表尾的標誌*/ } return 0; } /*求長函式的定義*/ int Length_List(Sqlist l) { int count=0; int i=0; while(-1!=l.store[i].next) { i=l.store[i].next;//i為下一個元素的地址,相當於後移節點,繼續判斷 count++;//說明這個節點不為空,count自增一直到迴圈到連結串列的結尾,此時得到的就是連結串列的長度了 } return count;//將連結串列的長度返回 } /*判空函式定義*/ int Judge_List_Empty(Sqlist l) { if(-1!=l.store[0].next) return -1;//說明此時的靜態連結串列不為空,首節點的next不等於-1,與上述的(1)相對應 return 0; } /*判滿函式定義*/ int Judge_List_Full(Sqlist l) { if(Max-1==Length_List(l)) return 1;//說明此時的靜態連結串列為滿 return 0; } /*靜態連結串列顯示函式*/ void Show_List(Sqlist l) { int i=0,k=1; i=l.store[i].next;//得到第一個元素的地址 while(-1!=l.store[i].next) { printf("No.%d 's data is %d\n",k++,l.store[i].data); i=l.store[i].next; }/*最後一個數據是沒有被輸出出來的,所以以下對於最後一個元素做了單獨的輸出*/ printf("No.%d 's data is %d\n",i,l.store[i].data); printf("There is no data left\n"); } /*靜態連結串列插入資料函式*/ int Insert_List(Sqlist *l) { int n,i=1,q,p=0; int k=1; printf("Please input the position of the new data:"); scanf("%d",&n); if(n<1||n>Length_List(*l)+1) return -1;//判斷插入的位置是否合法 for(i=1;i<n;i++) {p=(*l).store[p].next;}//找到插入位置的上一個位置 q=(*l).free_h;//找到空閒連結串列的首位置,給新元素預留 printf("Please input the new data:"); scanf("%d",&(*l).store[q].data);//在預留的位置上賦值新元素的內容 (*l).free_h=(*l).store[q].next;//空閒連結串列首位置下移 (*l).store[q].next=(*l).store[p].next;//將指定位置的上個元素的next位置改給新元素 (*l).store[p].next=q;//將新元素接入到指定位置的上一個元素後面 return 0; } int Research_List(Sqlist l) { int n,i,p=0; printf("Please input the position of the data be searched:"); scanf("%d",&n); if(n<1||n>Length_List(l))/*判斷查詢位置的合法性*/ return -1; else { for(i=1;i<=n;i++) {p=l.store[p].next;}//迴圈查詢到相應的位置 printf("The data you rearched is :%d\n",l.store[p].data); } return 0; } int Delete_List(Sqlist *l) { int i,n,p=0,q; printf("Please input the delete_data's position:"); scanf("%d",&n); if(n<1||n>Length_List(*l)) return -1;//判斷刪除的位置是否合法 for(i=1;i<n;i++) {p=(*l).store[p].next;}//找到刪除位置的上一個位置 q=(*l).store[p].next;//找到刪除的元素位置 (*l).store[p].next=(*l).store[q].next;//將刪除元素的上一個元素的next指向刪除元素的下一個位置 (*l).store[q].next=(*l).free_h;//將刪除的元素的空間加入到空閒連結串列的頭部 (*l).free_h=q;//空閒連結串列的起始地址改變為新加入的刪除元素的位置 return 0; }