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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

单链表基本操作(可执行程序),二级指针使用必要性的初步理解

發(fā)布時間:2025/5/22 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单链表基本操作(可执行程序),二级指针使用必要性的初步理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
#include <stdio.h> #include <stdlib.h> #include<time.h> #define ERROR 0; #define OK 1;//typedef typedef int Status; typedef int ElemType; typedef struct Node//定義帶頭結點的單鏈表的節(jié)點類型 {ElemType data;struct Node *next; }Node; typedef struct Node *LinkList;//操作函數(shù)聲明 Status CreateListHead(LinkList*L,int n); Status CreateListTail(LinkList *L,int n); Status GetElem(LinkList L,int i,ElemType *e); Status ListInsert(LinkList *L,int i,ElemType e); Status ListDelete(LinkList*L,int i,ElemType *e); Status DestroyList(LinkList *L); Status ListTraverse(LinkList L);int main() {LinkList L;int n=5;int e=0;int i=0;printf("請輸入需要產生的單鏈表長度(>=1):");scanf("%d",&n);CreateListTail(&L,n);printf("產生的單鏈表是:");ListTraverse(L);printf("請輸入你想要插入的位置和數(shù):");scanf("%d %d",&i,&e);ListInsert(&L,i,e);printf("插入后得到的新鏈表是:");ListTraverse(L);printf("你想要查看哪個位置的數(shù):");scanf("%d",&i);printf("該數(shù)是:");GetElem(L,i,&e);printf("\n");printf("你想要刪除哪個位置的數(shù):");scanf("%d",&i);ListDelete(&L,i,&e);printf("刪除以后的新鏈表是:");ListTraverse(L);printf("現(xiàn)在要銷毀鏈表釋放空間啦!\n");DestroyList(&L);}//單鏈表的整表創(chuàng)建,頭插法 Status CreateListHead(LinkList*L,int n) {LinkList p;int i;srand(time(0));*L=(LinkList)malloc(sizeof(Node));( *L)->next=NULL;if(n<1)return ERROR;for(i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;p->next=(*L)->next;(*L)->next=p;}return OK;} //單鏈表的整表創(chuàng)建,尾插法 Status CreateListTail(LinkList *L,int n) {LinkList p,r;int i;*L=(LinkList)malloc(sizeof(Node));( *L)->next=NULL;r=*L;srand(time(0));for (i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;r->next=p;r=p;}r->next=NULL;return OK; }//讀取單鏈表中的第i個元素 Status GetElem(LinkList L,int i,ElemType *e) {int j=1;LinkList p;p=L->next;while(p&&j<i){p=p->next;++j;}if(j>i||!p)return ERROR;*e=p->data;printf("%d",*e);return OK; }//在單鏈表中第i個位置之前插入一個新節(jié)點e Status ListInsert(LinkList *L,int i,ElemType e) {int j=1;LinkList p,s;p=*L;while(p&&j<i){p=p->next;++j;}if (!p||j>i)return ERROR;s=(LinkList)malloc(sizeof(Node));s->data=e;s->next=p->next;p->next=s;return OK; }//刪除單鏈表的第i個元素,并用e返回其值 Status ListDelete(LinkList*L,int i,ElemType *e) {int j=1;LinkList p,q;p=*L;while(p->next&&j<i){p=p->next;++j;}if (!(p->next)||j>i)return ERROR;q=p->next;p->next=q->next;* e=q->data;free(q);return OK; }//銷毀單鏈表 Status DestroyList(LinkList *L) {LinkList p,q;p=(*L)->next;while(p){q=p->next;free(p);p=q;}free(*L);*L=NULL;printf("鏈表銷毀成功!");return OK; } //打印單鏈表 Status ListTraverse(LinkList L) {LinkList p;p=L->next;while(p){printf("%d ",p->data);p=p->next;}printf("\n");return OK; }

程序測試結果:


關于二級指針使用的必要性,我是這樣理解的:

很多操作其實使用一級指針也可以實現(xiàn),但是在需要改變一級指針的值是就必須使用二級指針,例如,需要刪除頭結點或者生成鏈表時,L的值就需要變化,那么此時只有傳入二級指針才能達到修改L的值的目的,這種情況下傳入&L也是可行的。

下面舉兩個例子說明一下:

(1)

在鏈表已經生成的情況下,修改ListInsert函數(shù)為:

Status ListInsert(LinkList L,int i,ElemType e) {int j=1;LinkList p,s;p=L;while(p&&j<i){p=p->next;++j;}if (!p||j>i)return ERROR;s=(LinkList)malloc(sizeof(Node));s->data=e;s->next=p->next;p->next=s;return OK; }

程序仍然可以得到正確的結果。

(2)

但是在生成鏈表時,若只傳入一級指針,即修改CreateListTail為:

Status CreateListTail(LinkList L,int n) {LinkList p,r;int i;L=(LinkList)malloc(sizeof(Node));L->next=NULL;r=L;srand(time(0));for (i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;r->next=p;r=p;}r->next=NULL;return OK; }

則運行程序時,CodeBlocks會停止工作,這是因為在生成鏈表階段,需要將L的值傳出到主函數(shù),供后面的鏈表打印函數(shù)ListTraverse調用。若此處只傳入一級指針,則CreateListTail函數(shù)調用結束以后,L的值并沒有改變,相當于L仍指向主函數(shù)中定義時所指向的位置(野指針或者指向NULL,暫時還不是很清楚如果不初始化指向哪里),則后續(xù)調用打印函數(shù)會出錯。

總結:需要修改L的值時,必須傳入二級指針即func(LinkList *L),其他情況下傳一級指針即func(LinkList L)就ok。


總結

以上是生活随笔為你收集整理的单链表基本操作(可执行程序),二级指针使用必要性的初步理解的全部內容,希望文章能夠幫你解決所遇到的問題。

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