日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用C语言撸线性表

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用C语言撸线性表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 線性表可以說是最常見的一種數據結構了,在日常學習中使用也很多,今天用C語言實現以下簡單的線性表及基本操作。對于線性表來說可以分為順序存儲和鏈式存儲。順序存儲是提前分配一個連續的空間,可以實現隨機存取,一般采用數組實現;鏈式存儲的存儲空間不必是連續的,使用比較靈活,不會占用多余空間,一般采用指針實現現在我們要實現的是鏈式存儲。直接上代碼:

目錄

一、頭文件等準備部分:

二、定義以及初始化

三、判斷線性表是否為空

四、將線性表置空?

五、返回線性表元素個數

?六、返回第i個元素的值

七、找到第一個與給定元素相等的節點的位置?

八、在第i個元素之后加入新元素并將L長度加1?

九、刪除第i個元素之后將該元素的值返回并令表長度減一

十、輸出每個元素的值?

十一、頭插法?

十二、尾插法?

十三、主函數定義?


一、頭文件等準備部分:

//線性表的鏈式存儲 #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <io.h> #include <math.h> #include <time.h>//定義狀態常量 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0#define MAXSIZE 20 /* 存儲空間初始分配量 */ typedef int Status; /* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */ typedef int ElemType; /* ElemType類型根據實際情況而定,這里假設為int */

二、定義以及初始化

鏈式存儲結構的每個節點分為數據域data以及指針域,數據域存儲數據,指針域存儲結構體指針,指向的是下一個節點。具體如圖所示:?

//定義結構體 typedef struct Node{ElemType data;struct Node* next; }Node;

//定義線性表 typedef struct Node* LinkList;//初始化線性表 Status InitList(LinkList *L){*L=(LinkList)malloc(sizeof(Node)); /* 產生頭結點,并使L指向此頭結點 */if(!(*L)) /* 存儲分配失敗 */return ERROR;(*L)->next=NULL; /* 指針域為空 */return OK; }

?這里需要解釋幾點:

  • typedef (struct Node*) LinkList 這句可以加上括號理解,意思就是將指向Node類型的指針重新命名為Linklist,這樣做的目的主要是方便表示指向指針的指針(禁止套娃)

  • ?*L=(LinkList)malloc(sizeof(Node)):*是取內容運算符,則*L表示的指向節點的指針,malloc函數是動態申請一個節點
  • ??????????????

  • 這個線性表的頭節點生成了,并且next暫時為NULL之后的節點只需要接上就好,這里說一下頭節點:頭節點是沒有實際內容的節點,僅僅是為了將插入、刪除等操作統一起來

  • 三、判斷線性表是否為空

    /* 初始條件:順序線性表L已存在。操作結果:若L為空表,則返回TRUE,否則返回FALSE */ Status ListEmpty(LinkList L) { if(L->next)return FALSE;elsereturn TRUE; }

    四、將線性表置空?

    /* 初始條件:順序線性表L已存在。操作結果:將L重置為空表 */ Status ClearList(LinkList *L) { LinkList p,q;p=(*L)->next; /* p指向第一個結點 */while(p) /* 沒到表尾 */{q=p->next;free(p);p=q;}(*L)->next=NULL; /* 頭結點指針域為空 */return OK; }

    ?有的同學可能發現了,在這個函數的形式參數定義為(Linlist *L)即指向指針的指針,而上一個函數定義為(Linklist L)即指向結構體的指針,只是為啥呢?因為C語言的值傳遞機制,如果大家有興趣可以看看我的這篇文章。第三個函數僅僅是遍歷操作,并未涉及到傳參操作,不需要再多定義一個指針;第四個參數涉及到參數值的改變,如果單純在函數中進行值的傳遞,對主函數中原有參數的值是沒有任何影響的。大約就是下圖的意思哈哈哈哈

    五、返回線性表元素個數

    /* 初始條件:順序線性表L已存在。操作結果:返回L中數據元素個數 */ int ListLength(LinkList L) {int i=0;LinkList p=L->next; /* p指向第一個結點 */while(p) {i++;p=p->next;}return i; }

    同樣沒有參數值的改變,不需要指向指針的指針。

    ?六、返回第i個元素的值

    /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ /* 操作結果:用e返回L中第i個數據元素的值 */ Status GetElem(LinkList L,int i,ElemType *e) {int j;LinkList p; /* 聲明一結點p */p = L->next; /* 讓p指向鏈表L的第一個結點 */j = 1; /* j為計數器 */while (p && j<i) /* p不為空或者計數器j還沒有等于i時,循環繼續 */{ p = p->next; /* 讓p指向下一個結點 */++j;}if ( !p || j>i ) return ERROR; /* 第i個元素不存在 */*e = p->data; /* 取第i個元素的數據 */return OK; }

    七、找到第一個與給定元素相等的節點的位置?

    /* 初始條件:順序線性表L已存在 */ /* 操作結果:返回L中第1個與e滿足關系的數據元素的位序。*/ /* 若這樣的數據元素不存在,則返回值為0 */ int LocateElem(LinkList L,ElemType e) {int i=0;LinkList p=L->next;while(p){i++;if(p->data==e) /* 找到這樣的數據元素 */return i;p=p->next;}return 0; }

    八、在第i個元素之后加入新元素并將L長度加1?

    /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L), */ /* 操作結果:在L中第i個位置之后插入新的數據元素e,L的長度加1 */ Status ListInsert(LinkList *L,int i,ElemType e) { int j;LinkList p,s;p = *L; j = 1;while (p && j<i) /* 尋找第i個結點 */{p = p->next;++j;} if (!p || j > i) return ERROR; /* 第i個元素不存在 */s = (LinkList)malloc(sizeof(Node)); /* 生成新結點(C語言標準函數) */s->data = e; s->next = p->next; /* 將p的后繼結點賦值給s的后繼 */p->next = s; /* 將s賦值給p的后繼 */return OK; }

    九、刪除第i個元素之后將該元素的值返回并令表長度減一

    /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ /* 操作結果:刪除L的第i個數據元素,并用e返回其值,L的長度減1 */ Status ListDelete(LinkList *L,int i,ElemType *e) { int j;LinkList p,q;p = *L;j = 1;while (p->next && j < i) /* 遍歷尋找第i個元素 */{p = p->next;++j;}if (!(p->next) || j > i) return ERROR; /* 第i個元素不存在 */q = p->next;p->next = q->next; /* 將q的后繼賦值給p的后繼 */*e = q->data; /* 將q結點中的數據給e */free(q); /* 讓系統回收此結點,釋放內存 */return OK; }

    十、輸出每個元素的值?

    /* 初始條件:順序線性表L已存在 */ /* 操作結果:依次對L的每個數據元素輸出 */ Status ListTraverse(LinkList L) {LinkList p=L->next; /* p指向第一個結點 */while(p){visit(p->data);p=p->next;}printf("\t");return OK; }

    十一、頭插法?

    /* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(頭插法) */ void CreateListHead(LinkList *L, int n) {LinkList p;int i;srand(time(0)); /* 初始化隨機數種子 */*L = (LinkList)malloc(sizeof(Node));(*L)->next = NULL; /* 先建立一個帶頭結點的單鏈表 */for (i=0; i<n; i++) {p = (LinkList)malloc(sizeof(Node)); /* 生成新結點 */p->data = rand()%100+1; /* 隨機生成100以內的數字 */p->next = (*L)->next; (*L)->next = p; /* 插入到表頭 */} }

    說一下頭插法是從頭創建一個鏈表與在鏈表中插入一個元素不是一個意思,頭插法即每次新元素都是在表頭插入

    十二、尾插法?

    /* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(尾插法) */ void CreateListTail(LinkList *L, int n) {LinkList p,r;int i;srand(time(0)); /* 初始化隨機數種子 */*L = (LinkList)malloc(sizeof(Node)); /* L為整個線性表 */r=*L; /* r為指向尾部的結點 */for (i=0; i<n; i++) {p = (Node *)malloc(sizeof(Node)); /* 生成新結點 */p->data = rand()%100+1; /* 隨機生成100以內的數字 */r->next=p; /* 將表尾終端結點的指針指向新結點 */r = p; /* 將當前的新結點定義為表尾終端結點 */}r->next = NULL; /* 表示當前鏈表結束 */ }

    在尾插法中添加了一個尾指針。方便進行尾部的插入。?

    十三、主函數定義?

    int main() { LinkList L;ElemType e;Status i;int j,k;i=InitList(&L);printf("初始化L后:ListLength(L)=%d\n",ListLength(L));for(j=1;j<=5;j++)i=ListInsert(&L,1,j);printf("在L的表頭依次插入1~5后:L.data=");ListTraverse(L); printf("ListLength(L)=%d \n",ListLength(L));i=ListEmpty(L);printf("L是否空:i=%d(1:是 0:否)\n",i);i=ClearList(&L);printf("清空L后:ListLength(L)=%d\n",ListLength(L));i=ListEmpty(L);printf("L是否空:i=%d(1:是 0:否)\n",i);for(j=1;j<=10;j++)ListInsert(&L,j,j);printf("在L的表尾依次插入1~10后:L.data=");ListTraverse(L); printf("ListLength(L)=%d \n",ListLength(L));ListInsert(&L,1,0);printf("在L的表頭插入0后:L.data=");ListTraverse(L); printf("ListLength(L)=%d \n",ListLength(L));GetElem(L,5,&e);printf("第5個元素的值為:%d\n",e);for(j=3;j<=4;j++){k=LocateElem(L,j);if(k)printf("第%d個元素的值為:%d\n",k,j);elseprintf("沒有值為%d的元素\n",j);}k=ListLength(L); /* k為表長 */for(j=k+1;j>=k;j--){i=ListDelete(&L,j,&e); /* 刪除第j個數據 */if(i==ERROR)printf("刪除第%d個數據失敗\n",j);elseprintf("刪除第%d個的元素值為:%d\n",j,e);}printf("依次輸出L的元素:");ListTraverse(L); j=5;ListDelete(&L,j,&e); /* 刪除第5個數據 */printf("刪除第%d個的元素值為:%d\n",j,e);printf("依次輸出L的元素:");ListTraverse(L); i=ClearList(&L);printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));CreateListHead(&L,20);printf("整體創建L的元素(頭插法):");ListTraverse(L); i=ClearList(&L);printf("\n刪除L后:ListLength(L)=%d\n",ListLength(L));CreateListTail(&L,20);printf("整體創建L的元素(尾插法):");ListTraverse(L); return 0; }

    運行結果:?

    這樣一個線性表就寫好了,代碼基本上就是《大話數據結構》這本書的代碼,這本書真的很棒,與興趣的同學可以看一看。?

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的用C语言撸线性表的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。