一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看

C語(yǔ)言

鏈表的C語(yǔ)言實(shí)現方法

時(shí)間:2025-04-03 22:36:24 C語(yǔ)言 我要投稿

鏈表的C語(yǔ)言實(shí)現方法

  C語(yǔ)言的應用范圍廣泛,具備很強的數據處理能力,不僅僅是在軟件開(kāi)發(fā)上,而且各類(lèi)科研都需要用到C語(yǔ)言,適于編寫(xiě)系統軟件,三維,二維圖形和動(dòng)畫(huà),具體應用比如單片機以及嵌入式系統開(kāi)發(fā)。以下是小編為大家搜索整理鏈表的C語(yǔ)言實(shí)現方法,希望能給大家帶來(lái)幫助!更多精彩內容請及時(shí)關(guān)注我們應屆畢業(yè)生考試網(wǎng)!

  一、為什么用動(dòng)態(tài)內存分配

  但我們未學(xué)習鏈表的時(shí)候,如果要存儲數量比較多的同類(lèi)型或同結構的數據的時(shí)候,總是使用一個(gè)數組。比如說(shuō)我們要存儲一個(gè)班級學(xué)生的某科分數,總是定義一個(gè)float型(存在0.5分)數組:

  float score[30];

  但是,在使用數組的時(shí)候,總有一個(gè)問(wèn)題困擾著(zhù)我們:數組應該有多大?

  在很多的情況下,你并不能確定要使用多大的數組,比如上例,你可能并不知道該班級的學(xué)生的人數,那么你就要把數組定義得足夠大。這樣,你的程序在運行時(shí)就申請了固定大小的你認為足夠大的內存空間。即使你知道該班級的學(xué)生數,但是如果因為某種特殊原因人數有增加或者減少,你又必須重新去修改程序,擴大數組的存儲范圍。這種分配固定大小的內存分配方法稱(chēng)之為靜態(tài)內存分配。但是這種內存分配的方法存在比較嚴重的缺陷,特別是處理某些問(wèn)題時(shí):在大多數情況下會(huì )浪費大量的內存空間,在少數情況下,當你定義的數組不夠大時(shí),可能引起下標越界錯誤,甚至導致嚴重后果。

  那么有沒(méi)有其它的方法來(lái)解決這樣的外呢體呢?有,那就是動(dòng)態(tài)內存分配。

  所謂動(dòng)態(tài)內存分配就是指在程序執行的過(guò)程中動(dòng)態(tài)地分配或者回收存儲空間的分配內存的方法。動(dòng)態(tài)內存分配不象數組等靜態(tài)內存分配方法那樣需要預先分配存儲空間,而是由系統根據程序的需要即時(shí)分配,且分配的大小就是程序要求的大小。從以上動(dòng)、靜態(tài)內存分配比較可以知道動(dòng)態(tài)內存分配相對于景泰內存分配的特點(diǎn):

  1、不需要預先分配存儲空間;

  2、分配的空間可以根據程序的需要擴大或縮小。

  二、如何實(shí)現動(dòng)態(tài)內存分配及其管理

  要實(shí)現根據程序的需要動(dòng)態(tài)分配存儲空間,就必須用到以下幾個(gè)函數

  1、malloc函數

  malloc函數的原型為:

  void *malloc (unsigned int size)

  其作用是在內存的動(dòng)態(tài)存儲區中分配一個(gè)長(cháng)度為size的連續空間。其參數是一個(gè)無(wú)符號整形數,返回值是一個(gè)指向所分配的連續存儲域的起始地址的指針。還有一點(diǎn)必須注意的是,當函數未能成功分配存儲空間(如內存不足)就會(huì )返回一個(gè)NULL指針。所以在調用該函數時(shí)應該檢測返回值是否為NULL并執行相應的操作。

  下例是一個(gè)動(dòng)態(tài)分配的程序:

  [cpp] view plaincopy

  #include "malloc.h"

  #include "stdlib.h"

  main(void)

  {

  /*count是一個(gè)計數器,array是一個(gè)整型指針,也可以理解為指向一個(gè)整型數組的首地址*/

  int count;

  int *array;

  array=malloc(10 * sizeof(int));

  if(array==NULL)

  {

  printf("Out of memory!\n");

  exit(1);

  }

  /*給數組賦值*/

  for(count=0;count<10;count++)

  {

  array[count]=count;

  }

  /*打印數組元素*/

  for(count=0;count<10;count++)

  {

  printf("%2d\n",array[count]);

  }

  }

  上例中動(dòng)態(tài)分配了10個(gè)整型存儲區域,然后進(jìn)行賦值并打印。例中if((array(int *) malloc(10*sizeof(int)))==NULL)語(yǔ)句可以分為以下幾步:

  1)分配10個(gè)整型的連續存儲空間,并返回一個(gè)指向其起始地址的整型指針

  2)把此整型指針地址賦給array

  3)檢測返回值是否為NULL

  2、free函數

  由于內存區域總是有限的,不能不限制地分配下去,而且一個(gè)程序要盡量節省資源,所以當所分配的內存區域不用時(shí),就要釋放它,以便其它的變量或者程序使用。這時(shí)我們就要用到free函數。

  其函數原型是:

  void free(void *p)

  作用是釋放指針p所指向的內存區。

  其參數p必須是先前調用malloc函數或calloc函數(另一個(gè)動(dòng)態(tài)分配存儲區域的函數)時(shí)返回的指針。給free函數傳遞其它的值很可能造成死機或其它災難性的后果。

  注意:這里重要的是指針的值,而不是用來(lái)申請動(dòng)態(tài)內存的指針本身。例:

  int *p1,*p2;

  p1=malloc(10*sizeof(int));

  p2=p1;

  ……

  free(p2) /*或者free(p2)*/

  malloc返回值賦給p1,又把p1的值賦給p2,所以此時(shí)p1,p2都可作為free函數的參數。

  malloc函數是對存儲區域進(jìn)行分配的。

  free函數是釋放已經(jīng)不用的內存區域的。

  所以由這兩個(gè)函數就可以實(shí)現對內存區域進(jìn)行動(dòng)態(tài)分配并進(jìn)行簡(jiǎn)單的管理了。

  中 鏈表的C語(yǔ)言實(shí)現之單鏈表的實(shí)現

  一、單鏈表的建立

  有了動(dòng)態(tài)內存分配的基礎,要實(shí)現鏈表就不難了。

  所謂鏈表,就是用一組任意的存儲單元存儲線(xiàn)性表元素的一種數據結構。鏈表又分為單鏈表、雙向鏈表和循環(huán)鏈表等。我們先講講單鏈表。所謂單鏈表,是指數據接點(diǎn)是單向排列的。一個(gè)單鏈表結點(diǎn),其結構類(lèi)型分為兩部分:

  1、數據域:用來(lái)存儲本身數據

  2、鏈域或稱(chēng)為指針域:用來(lái)存儲下一個(gè)結點(diǎn)地址或者說(shuō)指向其直接后繼的指針。

  例:

  [cpp] view plaincopy

  typedef struct node

  {

  char name[20];

  struct node *link;

  }stud;

  這樣就定義了一個(gè)單鏈表的結構,其中char name[20]是一個(gè)用來(lái)存儲姓名的字符型數組,指針*link是一個(gè)用來(lái)存儲其直接后繼的指針。

  定義好了鏈表的結構之后,只要在程序運行的時(shí)候數據域中存儲適當的數據,如有后繼結點(diǎn),則把鏈域指向其直接后繼,若沒(méi)有,則置為NULL。

  下面就來(lái)看一個(gè)建立帶表頭(若未說(shuō)明,以下所指鏈表均帶表頭)的單鏈表的完整程序。

  [cpp] view plaincopy

  #include

  #include

  #include /*包含動(dòng)態(tài)內存分配函數的頭文件*/

  #define N 10 /*N為人數*/

  typedef struct node

  {

  char name[20];

  struct node *link;

  }stud;

  stud * creat(int n) /*建立單鏈表的函數,形參n為人數*/

  {

  stud *p,*h,*s;/* *h保存表頭結點(diǎn)的指針,*p指向當前結點(diǎn)的前一個(gè)結點(diǎn),*s指向當前結點(diǎn)*/

  int i;/*計數器*/

  if((h=(stud *)malloc(sizeof(stud)))==NULL) /*分配空間并檢測*/

  {

  printf("不能分配內存空間!");

  exit(0);

  }

  h->name[0]='\0'; /*把表頭結點(diǎn)的數據域置空*/

  h->link=NULL; /*把表頭結點(diǎn)的鏈域置空*/

  p=h; /*p指向表頭結點(diǎn)*/

  for(i=0;i

  {

  if((s=(stud *) malloc(sizeof(stud)))==NULL) /*分配新存儲空間并檢測*/

  {

  printf("不能分配內存空間!");

  exit(0);

  }

  p->link=s; /*把s的地址賦給p所指向的結點(diǎn)的鏈域,這樣就把p和s所指向的結點(diǎn)連接起來(lái)了*/

  printf("請輸入第%d個(gè)人的姓名",i+1);

  scanf("%s",s->name); /*在當前結點(diǎn)s的數據域中存儲姓名*/

  s->link=NULL;

  p=s;

  }

  return(h);

  }

  main()

  {

  int number; /*保存人數的變量*/

  stud *head; /*head是保存單鏈表的表頭結點(diǎn)地址的指針*/

  number=N;

  head=creat(number);/*把所新建的單鏈表表頭地址賦給head*/

  }

  這樣就寫(xiě)好了一個(gè)可以建立包含N個(gè)人姓名的單鏈表了。寫(xiě)動(dòng)態(tài)內存分配的程序應注意,請盡量對分配是否成功進(jìn)行檢測。

  鏈表的C語(yǔ)言實(shí)現之循環(huán)鏈表及雙向鏈表

  一、循環(huán)鏈表

  循環(huán)鏈表是與單鏈表一樣,是一種鏈式的存儲結構,所不同的是,循環(huán)鏈表的最后一個(gè)結點(diǎn)的指針是指向該循環(huán)鏈表的第一個(gè)結點(diǎn)或者表頭結點(diǎn),從而構成一個(gè)環(huán)形的鏈。

  循環(huán)鏈表的運算與單鏈表的運算基本一致。所不同的有以下幾點(diǎn):

  1、在建立一個(gè)循環(huán)鏈表時(shí),必須使其最后一個(gè)結點(diǎn)的指針指向表頭結點(diǎn),而不是象單鏈表那樣置為NULL。此種情況還使用于在最后一個(gè)結點(diǎn)后插入一個(gè)新的結點(diǎn)。

  2、在判斷是否到表尾時(shí),是判斷該結點(diǎn)鏈域的值是否是表頭結點(diǎn),當鏈域值等于表頭指針時(shí),說(shuō)明已到表尾。而非象單鏈表那樣判斷鏈域值是否為NULL。

  二、雙向鏈表

  雙向鏈表其實(shí)是單鏈表的改進(jìn)。

  當我們對單鏈表進(jìn)行操作時(shí),有時(shí)你要對某個(gè)結點(diǎn)的直接前驅進(jìn)行操作時(shí),又必須從表頭開(kāi)始查找。這是由單鏈表結點(diǎn)的結構所限制的。因為單鏈表每個(gè)結點(diǎn)只有一個(gè)存儲直接后繼結點(diǎn)地址的鏈域,那么能不能定義一個(gè)既有存儲直接后繼結點(diǎn)地址的鏈域,又有存儲直接前驅結點(diǎn)地址的鏈域的這樣一個(gè)雙鏈域結點(diǎn)結構呢?這就是雙向鏈表。

  在雙向鏈表中,結點(diǎn)除含有數據域外,還有兩個(gè)鏈域,一個(gè)存儲直接后繼結點(diǎn)地址,一般稱(chēng)之為右鏈域;一個(gè)存儲直接前驅結點(diǎn)地址,一般稱(chēng)之為左鏈域。在c語(yǔ)言中雙向鏈表結點(diǎn)類(lèi)型可以定義為:

  [cpp] view plaincopy

  typedef struct node

  {

  int data; /*數據域*/

  struct node *llink,*rlink; /*鏈域,*llink是左鏈域指針,*rlink是右鏈域指針*/

  }JD;

  當然,也可以把一個(gè)雙向鏈表構建成一個(gè)雙向循環(huán)鏈表。

  雙向鏈表與單向鏈表一樣,也有三種基本運算:查找、插入和刪除。

  雙向鏈表的基本運算:

  1、查找

  假若我們要在一個(gè)帶表頭的雙向循環(huán)鏈表中查找數據域為一特定值的某個(gè)結點(diǎn)時(shí),我們同樣從表頭結點(diǎn)往后依次比較各結點(diǎn)數據域的`值,若正是該特定值,則返回指向結點(diǎn)的指針,否則繼續往后查,直到表尾。

  下例就是應用雙向循環(huán)鏈表查找算法的一個(gè)程序。

  [cpp] view plaincopy

  #include

  #include

  #define N 10

  typedef struct node

  {

  char name[20];

  struct node *llink,*rlink;

  }stud;

  stud * creat(int n)

  {

  stud *p,*h,*s;

  int i;

  if((h=(stud *)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配內存空間!");

  exit(0);

  }

  h->name[0]=’\0’;

  h->llink=NULL;

  h->rlink=NULL;

  p=h;

  for(i=0;i

  {

  if((s= (stud *) malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配內存空間!");

  exit(0);

  }

  p->rlink=s;

  printf("請輸入第%d個(gè)人的姓名",i+1);

  scanf("%s",s->name);

  s->llink=p;

  s->rlink=NULL;

  p=s;

  }

  h->llink=s;

  p->rlink=h;

  return(h);

  }

  stud * search(stud *h,char *x)

  {

  stud *p;

  char *y;

  p=h->rlink;

  while(p!=h)

  {

  y=p->name;

  if(strcmp(y,x)==0)

  return(p);

  else p=p->rlink;

  }

  printf("沒(méi)有查找到該數據!");

  }

  void print(stud *h)

  {

  int n;

  stud *p;

  p=h->rlink;

  printf("數據信息為:\n");

  while(p!=h)

  {

  printf("%s ",&*(p->name));

  p=p->rlink;

  }

  printf("\n");

  }

  main()

  {

  int number;

  char studname[20];

  stud *head,*searchpoint;

  number=N;

  clrscr();

  head=creat(number);

  print(head);

  printf("請輸入你要查找的人的姓名:");

  scanf("%s",studname);

  searchpoint=search(head,studname);

  printf("你所要查找的人的姓名是:%s",*&searchpoint->name);

  }

【鏈表的C語(yǔ)言實(shí)現方法】相關(guān)文章:

鏈表的C語(yǔ)言實(shí)現方法編程學(xué)習06-12

C語(yǔ)言鏈表逆序方法技巧08-21

C語(yǔ)言數據結構實(shí)現鏈表逆序并輸出06-23

c語(yǔ)言鏈表的用法10-20

c語(yǔ)言鏈表的用法有哪些09-07

C語(yǔ)言的循環(huán)鏈表和約瑟夫環(huán)09-29

C語(yǔ)言單向鏈表環(huán)測試并返回環(huán)起始節點(diǎn)的方法10-04

C語(yǔ)言程序的實(shí)現09-27

C語(yǔ)言的HashTable簡(jiǎn)單實(shí)現10-12

一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看