靜態鏈表-C語言實現


1.靜態鏈表是在沒有指針的編程語言里對鏈表的一種實現
2.主要是用數組模擬指針
3.在這里,使用結構體使數組的每一個空間可以存儲一個數據元素(date)和一個游標(cur),游標的作用相當於鏈表的指針域,用於記錄下一元素的下標是多少
4.在沒有結構體(typedef)的語言中,也可以使用兩個並行數組實現此功能

此種結構在編程中不一定能用得到,但是這種思想非常巧妙,非常值得我們學習,不多說,直接上代碼,親測可行,有詳細注釋

#include<stdio.h>

#define MAXSIZE 1000                //靜態鏈表最大空間容量 typedef int ElemType;                //數據類型
typedef int Status;                    //返回值類型
#define OK 1                        //操作成功返回值
#define ERROR 0                        //操作失敗返回值 typedef struct                        //靜態鏈表的結構體
{ ElemType date; //結點數據
    int cur;                        //結點游標(相當於鏈表中的地址)
}StaticLinkList[MAXSIZE];            //表名

/* 靜態鏈表的初始化 第一個位置space[0]的cur指向第一個沒有數據的位置空間 最后一個位置space[MAXSIZE-1]的cur指向第一個有數據的位置空間,即頭結點 */ Status InitList(StaticLinkList space) { for(int i = 0; i < MAXSIZE-1; i++)            //為數組中的每個位置的游標賦值
        space[i].cur = i + 1; space[MAXSIZE-1].cur = 0;                    //使最后一個位置的游標為0
    return OK; } /* 模擬鏈表中的malloc函數,在數組中尋找空閑位置空間作為新結點 */
int malloc_SLL(StaticLinkList space) { int i = space[0].cur;                        //將備用鏈表的第一個結點位置賦值給i
    if(space[0].cur)                            //如果space[0].cur不是0,即備用鏈表非空
        space[0].cur = space[i].cur;                //將備用鏈表的下一個空閑位置賦值給space[0]
    return i; } /*獲得鏈表的長度*/
int ListLength(StaticLinkList L) { int i, l; l = 0;                    //記錄鏈表長度
    i = MAXSIZE - 1;        //獲得頭結點下標
    i = L[i].cur;            //獲得頭結點位置
    while(i)                //如果此下標 != 0
 { l++;                //長度加1
        i = L[i].cur;        //下標后移
 } return l;                //返回長度l
} /* 靜態鏈表的插入操作 */ Status InsertLinkList(StaticLinkList L, int i, ElemType e) { int j ,k, l; k = MAXSIZE-1;                            //獲取頭結點的下標
    if(i < 1 || i > ListLength(L)+1)        //判斷要插入的位置是否合理
        return ERROR; j = malloc_SLL(L);                        //獲得備用鏈表中的第一個位置下標
    if(j)                                    //如果此下標不是0,說明還有空間可用
 { L[j].date = e;                        //將此下標對應位置的數據域賦值為e
        for(l = 1; l < i; l++)                //遍歷鏈表,尋找i位置之前的結點
            k = L[k].cur;                    //獲得此結點的游標
        L[j].cur = L[k].cur;                //新結點的游標等於i-1位置的游標
        L[k].cur = j;                        //i-1位置的游標等於新結點的游標
        return OK;                            //操作成功
 } return ERROR;                            //操作失敗
} /*模擬free()函數,將刪除的結點空間加入備用空間*/
void free_SSL(StaticLinkList space, int i) { space[i].cur = space[0].cur;                    //刪除位置的游標等於0位置的游標
    space[0].cur = i;                                //0位置的游標等於當前結點
} /*靜態鏈表的刪除操作*/ Status DelLinkList(StaticLinkList L, int i) { int j, k; if(i < 1 || i > ListLength(L)+1)                //判斷刪除的位置是否合理
        return ERROR; k = MAXSIZE - 1;                                //獲得頭結點的游標
    for(j = 1; j < i; j++)                            //尋找i位置
        k = L[k].cur;                                //游標后移
    j = L[k].cur;                                    //將要刪除的位置下標賦值給j
    L[k].cur = L[j].cur;                            //使刪除結點的前一結點的游標指向刪除結點的游標
    free_SSL(L, j);                                    //釋放刪除的結點
    return OK; } /*靜態鏈表的遍歷操作*/
void PrintLinkList(StaticLinkList L) { int i; int j = MAXSIZE - 1;                        //獲得數組最后一個位置的下標
    j = L[j].cur;                                //獲得此下標的游標值,即頭結點的下標 // printf("長度為%d\n",ListLength(L));
    for(i = 1; i <= ListLength(L); i++)            //遍歷此表
 { printf("第%d個結點的數據是:%d\n", i, L[j].date);                //輸出每個結點的數據
        j = L[j].cur;                            //獲得下一結點的游標
 } } void main() { StaticLinkList L; //創建鏈表L
    int i, e;            //i為元素位置,e為元素內容

    while(true) { printf("請選擇對靜態鏈表的操作:\n"); printf("1.初始化\n"); printf("2.插入\n"); printf("3.刪除\n"); printf("4.輸出\n"); printf("5.退出\n"); int a; scanf("%d", &a); switch(a) { case 1: if(InitList(L)) printf("初始化成功\n"); else printf("初始化失敗\n"); break; case 2: printf("請輸入需要插入的位置:"); scanf("%d", &i); printf("請輸入需要插入的元素:"); scanf("%d", &e); if(InsertLinkList(L, i, e)) printf("插入成功\n"); else printf("插入失敗\n"); break; case 3: printf("請輸入需要刪除的位置:"); scanf("%d", &i); if(DelLinkList(L, i)) printf("刪除成功\n"); else printf("刪除失敗\n"); break; case 4: PrintLinkList(L); break; case 5: return; default: printf("選擇錯誤\n"); break; } } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM