1. 程式人生 > >C語言連結串列超簡單教程

C語言連結串列超簡單教程

筆者作為一名C語言的初學者,在剛接觸連結串列時,幾乎找不到教程能用很通俗易懂的語言去講解連結串列。大多數時候找到的關於連結串列的教程,或許是生硬的塞給讀者一大段程式碼,或許是使用了一些過於專業的詞彙,對於萌新非常地不友好。這就是我寫這篇教程的原因。

好吧,即使這篇教程會相對簡單,但是在閱讀之前,讀者還是需要首先簡單瞭解結構體部分和指標部分的內容。

好,那我們就開始吧。

首先通俗地解釋一下:連結串列是一種特殊的結構體,建立連結串列只需要下面這些程式碼:


struct node
{
	int num;
	struct node *next;
};

到此為止,你就成功建立了一個連結串列。

我們來詳細分析一下:首先我們使用了建立結構體的標準格式,建立了一個struct node,

struct node有兩個成員(int, struct node),在這個結構中,int型別非常的平淡無奇,而struct node本來是我們定義的結構體,但是在結構體裡面的成員裡再次出現(這時很多教程就會告訴你這是C語言裡先使用後定義的特例云云,但我們不管),並且定義了一個指標變數,根據我們對指標的瞭解,某一型別的指標指向相同型別的資料(void是空指標,int型指標指向整形變數,char型指標指向字元型變數),那麼struct node型指標就指向struct node型結構,我們先看一個圖瞭解一下:

那麼這個特殊的指標是怎麼運作呢?

這個特殊的指標,指向另一個結構,而這個結構同樣擁有一個指向其他結構的指標,就構成了這樣一個關係:


迴圈下去,就會產生一條“鏈”,連結串列分為單向連結串列雙向連結串列以及迴圈連結串列,大家可以自行去了解不同種類的連結串列,這裡我們以單向連結串列為例子,分析一下對連結串列的操作。(請先行了解malloc函式的作用,它是必不可少的)

#include <stdio.h>
#include <stdlib.h>

struct node
{
	int num;
	struct node *next;
};

int main()
{
	struct node *head;    //宣告表頭head(連結串列開始的位置)
	head=NULL; 		//建一個空表
	struct node *p1,*p2;
	int i=1;
	//利用malloc()申請分配節點(也就是一個地址)
	p1=p2=(struct node*)malloc(sizeof(struct node));		//新節點
	printf("請輸入值,值小於等於0結束,值存放地址為:p1_ADDR= %d\n",p1); 
    scanf("%d",&p1->num);
    p1->no=i;
    p1->next=NULL;
    while(p1->num>0)  		//輸入的節點數值大於0
	{
		if(head==NULL)
			head=p1;  		//空表,接入表頭
		else
			p2->next=p1;  	//非空表,接到表尾
		p2=p1;
		
		p1=(struct node*)malloc(sizeof(struct node));		//下一個新節點
		i=i+1; 
   		printf("請輸入值,值小於等於0結束,值存放地址為:p%d_ADDR= %d\n",i,p2); 
   		scanf("%d",&p1->num);//輸入節點的值
   		p1->no=i;
   		//判斷一下是否有後續節點要接入連結串列,若無則結束;  
	}
	free(p1);		 //申請到的沒錄入,所以釋放掉  
 	p1=NULL;  	//使指向空  
  	p2->next = NULL; 	//到表尾了,指向空  
  	printf("連結串列輸入結束(END)\n");
	getchar();
    return 0;
}

這段程式執行完畢後,我們得到了連結串列表頭head,但是其餘空間都是系統分配的,我們並不能直接找到對應的變數。但是這就是單向連結串列的神奇之處,只要知道表頭,就可以一步一步摸到表尾。不過在此之前,我們要先理清思路。

首先,head->next代表什麼?

它既是首個結構的一個成員,也是第二個結構的地址。

那麼,head->next->next又是什麼呢?

它既是第二個結構的一個成員,也是第三個結構的地址。

所以,我們可以在代表結束的getchar();語句之前插入printf(“%d”,head->next->next->num);試一試,你會發現,如果你的節點達到了三個或更多的話,這條語句能夠精準地輸出第三個結構裡num的值。

現在想一想,怎麼將剛剛建立的單向連結串列所有的節點反向?

反向也就是將所有結構中的指標成員從指向下一個結構改為指向上一個結構。

想好了嗎?我們開始了哦。

我們首先從表頭開始操作,建立三個struct node型指標x1,x2,temp作為暫存器(為什麼是三個呢?想想我們在學習交換a,b兩個變數的值時,是c=a;a=b;b=c;這個樣子的)。

先儲存好head->next->next指向的地址 x1=head->next->next;

然後把x1放一邊兒涼快去。

再儲存第二個結構的地址 x2=head->next;

之後讓第二個結構裡的成員next指向首個結構 head->next=head;

再然後令表頭指向空 head=NULL;

第一步反向就完成了,那麼接下來再完成第二步。

還記得我們之前使用的x1和x2嗎?馬上就能派上用場了。

因為head指向了NULL,故head已經不復存在,但我們還有temp。

先把x1的值留住 temp=x1;

而x1再往後移動一次x1=x1->next;    //這裡將x1->next看作下一結構

此時x1就又可以放在一邊兒涼快了。(x1:”嚶嚶嚶”)

我們的目的是讓第三個結構裡的指標成員指向第二個結構,找找我們在第一步裡做了什麼。

第二個結構的地址被儲存在x2中,第三個結構的地址被儲存在了temp中

temp->next=x2;   //這裡將temp->next看作成員

這樣就又完成了一次逆向,不過還沒結束這一步,因為這是迴圈操作,要保持語句一致性。

所以我們還要將x2向後移動一次x2=temp;

後面每一步的操作,都和第二步類似,但是,迴圈結束是什麼時候呢?

由於x1每次只是單純後移,幾乎沒有操作,那麼,後移之後的x1裡的next是不是空指標(NULL)就成了關鍵。

if(x1->next==NULL)
{
	temp->next=x2;
	x1->next=temp;
	head=x1;
	break;
}

此時,表頭地址再次存入了head,不過單向連結串列已經反向(這個教程是有陷阱的,如果連結串列比較短,在x1=head->next->next;時就會崩潰,想想怎麼解決吧)。

現在,您已經可以去閱讀其他的教程,更加詳細地研究連結串列。

如果您在這篇文章中發現問題,歡迎隨時提出寶貴的意見,我將不甚感激,作為一名初學者,對於很多專業的知識不瞭解,也因此避免了使用難以理解的專業詞彙進行講解,如有錯誤,請以標準文件為準。


相關推薦

C語言連結串列簡單教程

筆者作為一名C語言的初學者,在剛接觸連結串列時,幾乎找不到教程能用很通俗易懂的語言去講解連結串列。大多數時候找到的關於連結串列的教程,或許是生硬的塞給讀者一大段程式碼,或許是使用了一些過於專業的詞彙,對於萌新非常地不友好。這就是我寫這篇教程的原因。好吧,即使這篇教程會相對簡單

C語言連結串列(詳細)

前言:之前學習連結串列的時候總會遇到一些問題 也看了好多人的文章感覺有些不是太實用 然後後來也是自己摸索才大概寫出來的. 在真正的開發中會把連結串列的增刪改查寫到函式裡 但是刪除有點麻煩 找了很多都是刪除第幾個 而不是刪除某個值對應的節點 讓我很難受 所以想寫一些連結串列的操作分享

從零開始的c語言連結串列學習 001--建立一個最簡單基礎的連結串列

因為各種原因,儘管c語言期末考也拿了八十多分,卻仍然對連結串列處在完全甍逼的狀態,以至於之後的資料結構課聽天書,實驗課做不出來,於是決定重學一波連結串列的知識,特此記錄筆記 001—建立一個簡單的連結串列 1.1 認識連結串列 所謂連結串列,一言蔽之就是一連串帶

c語言連結串列寫的一個簡單的學生管理系統

在大學由於在學完c語言之後老師佈置了一個寫學生管理系統的課設我寫了一個簡單的學生管理 系統,話不多說,直接上原始碼。 #include<stdio.h> #include<stdlib.h> #include<string.h> char

c語言連結串列詳解(詳細)

連結串列是一種常見的基礎資料結構,結構體指標在這裡得到了充分的利用。連結串列可以動態的進行儲存分配,也就是說,連結串列是一個功能極為強大的陣列,他可以在節點中定義多種資料型別,還可以根據需要隨意增添,刪除,插入節點。連結串列都有一個頭指標,一般以head來表示,存放的是一個地

使用C語言連結串列實現商品管理系統

#include <stdio.h> #include <stdlib.h> #include <windows.h> #define bool char #define true 1 #define false 0 #define NUM 1

5 種排序演算法--C語言連結串列

原始碼地址 GitHub:https://github.com/GYT0313/C-DataStructure/blob/master/sortIn5.c 包括: 氣泡排序 快速排序 選擇排序 插入排序 希爾排序 執行: 注意:

1870 Problem B C語言-連結串列排序

問題 B: C語言-連結串列排序 時間限制: 1 Sec  記憶體限制: 128 MB 提交: 86  解決: 71 [提交][狀態][討論版][命題人:外部匯入] 題目描述 已有a、b兩個連結串列,每個連結

C語言連結串列的建立插入等綜合實戰

系本人原創,轉載請註明出處: 程式設計老師讓寫一個連結串列的綜合運用,包括建立,檢視某個節點,刪除某個節點,插入某個節點,以及連結串列的逆序,還必須要有出錯提示和返回。QaQ,,,看見這麼多東西我就想嚶嚶嚶, 先放上鍊表的結構體: typedef struct stud

C語言連結串列節點插入與刪除

線性表操作 順序表是我們資料結構中的基本儲存形式,現在給定一個順序表,有如下操作: Insert X Y:在順序表中X位置插入Y元素,遍歷輸出當前順序表的所有元素。 Delete X:刪除順序表中的X元素,如果有多個X元素,只刪除第一個X,遍歷輸出當前順序的所有

C語言連結串列:遍歷,頭插,尾插,中間插入;頭節點刪除,尾節點刪除,中間刪除的操作

/****************************************************************************************************************************************

一步一步教你從零開始寫C語言連結串列---構建一個連結串列

為什麼要學習連結串列? 連結串列主要有以下幾大特性: 1、解決陣列無法儲存多種資料型別的問題。 2、解決陣列中,元素個數無法改變的限制(C99的變長陣列,C++也有變長陣列可以實現)。 3、陣列移動元素的過程中,要對元素進行大範圍的移動,很耗時間,效率也不高。

C語言連結串列多項式的加法

6-3 Add Two Polynomials (20 point(s)) Write a function to add two polynomials. Do not destroy the input. Use a linked list implementation

C語言連結串列的5種常見操作

C語言連結串列的5種常見操作 單鏈表反轉 連結串列中環的檢測 兩個有序的連結串列合併 刪除連結串列倒數第n個結點 求連結串列的中間結點 Ref typedef struct list{ int i

C語言 連結串列的建立,插入,刪除,列印

#include <stdio.h> #include <stdlib.h> #include <memory.h> //結構體定義 struct Node{ char name[10]; int score; s

C語言連結串列頭插法,尾插法,排序

題目描述 火車站要組裝一列動車。每列車廂有車廂編號、座位數和座位等級。現在請你把它們組裝起來,要求按照車廂號碼升序排列,並輸出每列車廂的資訊。請使用連結串列來實現。 輸入 輸入有多組。 每組有多行。第一行是個正整數n,表示車廂數目。接下來有n行資料,每行資料有3個值,分別是車廂編號、

C語言 連結串列的插入和刪除

#include <stdio.h>#include <malloc.h>#include "SeqList.h"typedef unsigned int TSeqListNode;typedef struct _tag_SeqList{    int

C語言連結串列實現佇列操作

還是操作佇列,但是這次換成連結串列,但是要注意出隊的操作。 一般的思維是在出隊的時候,刪除頭結點的下一個節點,這樣的話確實可以將佇列中的節點全部刪除,但是如果我們將最後一個節點刪除的時候,我們的演算法就將tail指標賦值為NULL,這時如果再進行入隊操作的時候,就會發生段錯

C 語言 連結串列的建立與列印

/* 包含的標頭檔案 */ #include <stdio.h> #include <stdlib.h> /* 定義一個表示連結串列的結構體指標

C++語言--連結串列-7.1----連結串列、動態連結串列

前言:我愛程式設計,編程使我快樂!! 我們知道,陣列式計算機根據事先定義好的陣列型別與長度自動為其分配一連續的儲存單元,相同陣列的位置和距離都是固定的,也就是說,任何一個數組元素的地址都可一個簡單的公式計算出來,因此這種結構可以有效的對陣列元素進行隨機訪問。但若對陣列