国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。

這篇具有很好參考價值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

大家好,今天我們來學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)中的順序表與鏈表!源碼在最后附上

首先我們先來認(rèn)識一下順序表

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

**如上圖所示:很多人會以為數(shù)組就是順序表,順序表就是數(shù)組,這種理解時錯誤的。

數(shù)組:

數(shù)組是相同數(shù)據(jù)類型的元素按一定順序排列的的集合。數(shù)組中的元素存儲在一個連續(xù)性的內(nèi)存塊中,并通過索引來訪問。

簡單的說,數(shù)組是在物理空間中連續(xù)存儲的相同數(shù)據(jù)類型的元素的集合。

而順序表:

順序表,全名順序存儲結(jié)構(gòu),是線性表的一種。(線性表(linear list)是數(shù)據(jù)結(jié)構(gòu)的一種,一個線性表是?n 具有相同特性的數(shù)據(jù)元素的有限序列。線性表在邏輯上是線性結(jié)構(gòu),也就說是連續(xù)的一條直線,但是在物理結(jié)構(gòu)上并不一定是連續(xù)的。常見的線性表:順序表、鏈表、棧、隊列、字符串等。

順序表不僅要求數(shù)據(jù)在邏輯上是連續(xù)的一條直線,還要求用一段物理地址連續(xù)的存儲單元以存儲表中數(shù)據(jù)元素,一般情況下采用數(shù)組存儲。

總結(jié):

順序表是在計算機(jī)內(nèi)存中以數(shù)組的形式保存的線性表,只能從頭開始連續(xù)存儲。
此處將「數(shù)組」理解為物理結(jié)構(gòu),「順序表」理解為邏輯結(jié)構(gòu)比較合理
我們可以用數(shù)組實現(xiàn)順序表,但我們同樣可以用數(shù)組實現(xiàn)二叉樹、隊列等結(jié)構(gòu),因此不能直接認(rèn)為順序表就是數(shù)組
在順序表中我們可以定義表中元素個數(shù)、表空間大小等變量,在數(shù)組中是沒有的

? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法? ? ? ? ? ? ? ? ?

首先我們來學(xué)習(xí)一下順序表的靜態(tài)存儲

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

而順序表的靜態(tài)存儲又存在明顯的缺陷和不足

不知道需要給確定的多少個空間,N給小了不夠用,N給大了會浪費。

那么如何解決這個問題呢?

在這里我們使用malloc來動態(tài)開辟空間,再使用realloc來進(jìn)行空間的管理。

順序表的動態(tài)存儲:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

在這里我們要注意realloc擴(kuò)容存在異地擴(kuò)容原地擴(kuò)容倆種情況;

注意地址,當(dāng)你realloc的空間沒有那么大時,這里就是原地擴(kuò)容

? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法??

注意地址,當(dāng)你realloc的空間很大的時候,就會異地擴(kuò)容

? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

這里先讓我們簡單的來實現(xiàn)順序表的幾個功能:(完整功能最后附上源碼)

實現(xiàn)順序表的頭插,即往前邊插進(jìn)去數(shù)據(jù):

?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

實現(xiàn)順序表中間插入數(shù)據(jù)

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

實現(xiàn)順序表的刪除

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

通過以上學(xué)習(xí),我們大概了解了順序表的一些基礎(chǔ)知識,那么順序表是否存在一些缺點呢?

順序表的缺點

1.尾部插入數(shù)據(jù)還不錯,但是頭部和中間插入刪除數(shù)據(jù),效率低下,需要挪動數(shù)據(jù)。?

2.滿了之后只能擴(kuò)容,而擴(kuò)容是有一定的消耗的,擴(kuò)容一般是存在一定的空間浪費(假如空間100已經(jīng)滿了,擴(kuò)容到200,只需要插入120個數(shù)據(jù),那么就有80個浪費掉了)

3.一次擴(kuò)的多了,可能浪費掉了;一次擴(kuò)的少了,有需要頻繁去擴(kuò)容。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

接下來讓我們來學(xué)習(xí)鏈表?

鏈表:鏈表采用鏈?zhǔn)酱鎯Y(jié)構(gòu),其內(nèi)存空間不連續(xù)

而鏈表分為單鏈表雙鏈表,我們先來學(xué)習(xí)單鏈表

? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

? ? ? ? ? ? ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

它是由一個一個結(jié)點結(jié)合在一起的,而每個節(jié)點的地址沒有關(guān)聯(lián),都是隨機(jī)的,東一個西一個。

注意單鏈表的最后一個結(jié)點指向NULL;

這里我們簡單的定義一個單鏈表:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法?

如何去訪問鏈表里的各個結(jié)點呢:我們定義一個cur指針指向單鏈表的頭節(jié)點,然后通過cur->next來依次訪問剩下的結(jié)點,如果cur==NULL,說明鏈表訪問完了。

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

接下來我們來實現(xiàn)單鏈表幾個基本的功能:(完整源碼結(jié)尾附上)

單鏈表的尾插

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法 ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

這里需要額外注意:因為phead是plist的臨時拷貝,使用要注意二級指針與一級指針的使用,當(dāng)然不使用二級指針也是可以 ,也有不同的寫法,這里這樣寫是讓大家小心注意一下其中的大坑。

單鏈表的頭插:

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

?

單鏈表的尾刪:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

需要注意,這里需要區(qū)分一個結(jié)點多個結(jié)點的不同情況。

單鏈表的頭刪:

? ? ? ? ? ? ? ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

這里需要注意:我們的思路是把頭節(jié)點的指向原本頭結(jié)點的下一個結(jié)點,然后還需要free掉原本的頭節(jié)點,這里會出現(xiàn)一種很常見的錯誤

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

先free掉tmp后,就沒辦法再進(jìn)行頭結(jié)點的鏈接,丟失了地址。

正確的寫法:(大家注意區(qū)分)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

關(guān)于鏈表還有一個知識點,就是哨兵位

? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

哨兵位就是在頭節(jié)點的前面給它再加一個結(jié)點,讓它充當(dāng)頭節(jié)點,但它不存儲具體的數(shù)據(jù),只是更方便進(jìn)行頭插頭刪等操作,哨兵位的含金量不是很高,有時候方便用來刷OJ題,這里大家簡單了解下,有興趣的朋友自己敲敲代碼試一下把。

單鏈表我們就學(xué)到這里,接下來我們學(xué)習(xí)一下雙鏈表:

這里我們先再來了解下鏈表有哪些分類:

? ? ? ??【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

我們注意到,單鏈表和雙鏈表的區(qū)別是:單鏈表一個結(jié)點只能指向下一個結(jié)點,而雙邊表一個結(jié)點可以指向前一個結(jié)點也可以指向后一個結(jié)點。

循環(huán)鏈表的特殊之處則是尾結(jié)點直接指向了頭節(jié)點,實現(xiàn)了一個循環(huán)。

接下來我們先來比較一下倆種鏈表:

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

我們主要學(xué)習(xí)一下帶頭雙向循環(huán)鏈表:?

根據(jù)上面單鏈表的學(xué)習(xí),我們簡單寫幾個功能讓加強(qiáng)大家對雙向鏈表的理解:

帶頭雙向循環(huán)鏈表的尾插:

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

我們可以明顯感受到,雙向循環(huán)鏈表的數(shù)據(jù)處理只需要幾個簡單的指向就可以簡單完成;

帶頭雙向循環(huán)鏈表的尾刪:

【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。,鏈表,數(shù)據(jù)結(jié)構(gòu),c語言,算法

知識的分享就結(jié)束了,接下來附上順序表與鏈表的源碼:(因為內(nèi)容較多,所以不是很全,但有具體的框架,大家可以根據(jù)自己的需要進(jìn)行補(bǔ)全)

順序表:

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


typedef int SLDataType;

typedef struct SeqList
{
	SLDataType* a;
	int size;      // 有效數(shù)據(jù)
	int capacity;  // 空間容量
}SL;

void SLInit(SL* psl);
void SLDestroy(SL* psl);

void SLPrint(SL* psl);
void SLCheckCapacity(SL* psl);

// 頭尾插入刪除
void SLPushBack(SL* psl, SLDataType x);
void SLPushFront(SL* psl, SLDataType x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);

// 任意下標(biāo)位置的插入刪除
void SLInsert(SL* psl, int pos, SLDataType x);
void SLErase(SL* psl, int pos);

?SeqList.c

#include"SeqList.h"

void SLInit(SL* psl)
{
	assert(psl);

	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;
}

void SLDestroy(SL* psl)
{
	assert(psl);

	if (psl->a != NULL)
	{
		free(psl->a);
		psl->a = NULL;
		psl->size = 0;
		psl->capacity = 0;
	}
}

void SLPrint(SL* psl)
{
	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

void SLCheckCapacity(SL* psl)
{
	assert(psl);

	if (psl->size == psl->capacity)
	{
		int newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(psl->a, sizeof(SLDataType)*newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		psl->a = tmp;
		psl->capacity = newCapacity;
	}
}

// 10:37
void SLPushBack(SL* psl, SLDataType x)
{
	assert(psl);

	SLCheckCapacity(psl);

	psl->a[psl->size] = x;
	psl->size++;
}

void SLPushFront(SL* psl, SLDataType x)
{
	assert(psl);

	SLCheckCapacity(psl);

	// 挪動數(shù)據(jù)
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[0] = x;
	psl->size++;
}

void SLPopBack(SL* psl)
{
	assert(psl);

	// 空
	// 溫柔的檢查
	/*if (psl->size == 0)
	{
		return;
	}*/

	// 暴力檢查
	assert(psl->size > 0);

	//psl->a[psl->size - 1] = -1;
	psl->size--;
}

// 10:47
void SLPopFront(SL* psl)
{
	assert(psl);

	// 暴力檢查
	assert(psl->size > 0);

	int begin = 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		++begin;
	}

	psl->size--;
}

// 注意pos是下標(biāo)
// size是數(shù)據(jù)個數(shù),看做下標(biāo)的話,他是最后一個數(shù)據(jù)的下一個位置
void SLInsert(SL* psl, int pos, SLDataType x)
{
	assert(psl);
	assert(pos >= 0 && pos <= psl->size);

	SLCheckCapacity(psl);

	// 挪動數(shù)據(jù)
	int end = psl->size - 1;
	while (end >= pos)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[pos] = x;
	psl->size++;
}

void SLErase(SL* psl, int pos)
{
	assert(psl);
	assert(pos >= 0 && pos < psl->size);

	// 挪動覆蓋
	int begin = pos + 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		++begin;
	}

	psl->size--;
}

Test.c:

#include<stdio.h>
#include"SeqList.h"


void TestSL1()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	SLPushBack(&sl, 7);
	SLPushBack(&sl, 8);
	SLPushBack(&sl, 9);
	SLPrint(&sl);

	SLPushFront(&sl, 10);
	SLPushFront(&sl, 20);
	SLPushFront(&sl, 30);
	SLPushFront(&sl, 40);
	SLPrint(&sl);

	SLDestroy(&sl);
}

void TestSL2()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(&sl);

	SLPopBack(&sl);
	SLPrint(&sl);

	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPrint(&sl);



	SLPushFront(&sl, 10);
	SLPushFront(&sl, 20);
	SLPushFront(&sl, 30);
	SLPushFront(&sl, 40);
	SLPrint(&sl);

	SLDestroy(&sl);
}

void TestSL3()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(&sl);

	SLPopFront(&sl);
	SLPrint(&sl);

	SLPopFront(&sl);
	SLPrint(&sl);

	SLPopFront(&sl);
	SLPrint(&sl);

	SLPopFront(&sl);
	SLPrint(&sl);

	SLPopFront(&sl);
	SLPrint(&sl);

	//SLPopFront(&sl);
	//SLPrint(&sl);
}

void TestSL4()
{
	

	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(&sl);

	SLInsert(&sl, 2, 20);
	SLPrint(&sl);

	SLInsert(&sl, 6, 20);
	SLPrint(&sl);

	SLInsert(&sl, 0, 20);
	SLPrint(&sl);

	SLInsert(&sl, 10, 20);
	SLPrint(&sl);

	SLDestroy(&sl);
}

void TestSL5()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(&sl);

	SLErase(&sl, 3);
	SLPrint(&sl);

	SLErase(&sl, 3);
	SLPrint(&sl);

	//SLErase(&sl, 3);
	//SLPrint(&sl);
}

int main()
{
	TestSL5();
	return 0;
}

單鏈表:?

?SList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SLNDataType;

// Single List
typedef struct SListNode
{
	SLNDataType val;
	struct SListNode* next;
}SLNode;

void SLTPrint(SLNode* phead);
void SLTPushBack(SLNode** pphead, SLNDataType x);
void SLTPushFront(SLNode** pphead, SLNDataType x);

void SLTPopBack(SLNode** pphead);
void SLTPopFront(SLNode** pphead);

SLNode* SLTFind(SLNode* phead, SLNDataType x);

// pos?
SLNode* SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x);

// ?posλ
void SLTErase(SLNode** pphead, SLNode* pos);
void SLTDestroy(SLNode** pphead);

SList.c

#include"SList.h"

void SLTPrint(SLNode* phead)
{
	SLNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("NULL\n");
}

SLNode* CreateNode(SLNDataType x)
{
	SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->val = x;
	newnode->next = NULL;
	return newnode;
}

void SLTPushBack(SLNode** pphead, SLNDataType x)
{
	SLNode* newnode = CreateNode(x);

	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		// 找尾
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		tail->next = newnode;
	}	
}

void SLTPushFront(SLNode** pphead, SLNDataType x)
{
	SLNode* newnode = CreateNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

void SLTPopBack(SLNode** pphead)
{
	// 溫柔的檢查
	//if (*pphead == NULL)
	//	return;

	// 空
	assert(*pphead);

	// 1、一個節(jié)點
	// 2、一個以上節(jié)點
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		// 找尾
		/*SLNode* prev = NULL;
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}

		free(tail);
		tail = NULL;

		prev->next = NULL;*/

		SLNode* tail = *pphead;
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}

		free(tail->next);
		tail->next = NULL;
	}
}

void SLTPopFront(SLNode** pphead)
{

	assert(*pphead);

	
	SLNode* tmp = *pphead;
	free(tmp);
	*pphead = (*pphead)->next;
}

Test.c

#include"SList.h"

void TestSLT1()
{
	SLNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	SLTPopBack(&plist);
	SLTPrint(plist);

	//SLTPopBack(&plist);
	//SLTPrint(plist);
}

void TestSLT2()
{
	SLNode* plist = NULL;
	SLTPushFront(&plist, 1);
	SLTPushFront(&plist, 2);
	SLTPushFront(&plist, 3);
	SLTPushFront(&plist, 4);
	SLTPrint(plist);

	SLTPopFront(&plist);
	SLTPrint(plist);


	//SLNode* pos = SLTFind(plist, 3);
	//SLTInsert(&plist, pos, 30);
}

//int main()
//{
//	TestSLT2();
//
//	return 0;
//}

struct ListNode
{
	struct ListNode* next;
	int val;
};

struct ListNode* removeElements(struct ListNode* head, int val)
{
	struct ListNode* prev = NULL;
	struct ListNode* cur = head;

	//while(cur != NULL)
	while (cur)
	{
		if (cur->val == val)
		{
			struct ListNode* next = cur->next;
			free(cur);

			if (prev)
				prev->next = next;

			cur = next;
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}

	return head;
}

int main()
{
	struct ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* n2 = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* n3 = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* n4 = (struct ListNode*)malloc(sizeof(struct ListNode));
	n1->val = 7;
	n2->val = 7;
	n3->val = 7;
	n4->val = 7;

	n1->next = n2;
	n2->next = n3;
	n3->next = n4;
	n4->next = NULL;

	struct ListNode* head = removeElements(n1, 7);

	return 0;
}

?文章來源地址http://www.zghlxwxcb.cn/news/detail-833483.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)與算法】順序表與鏈表(單鏈表和雙鏈表)超詳解圖示與源碼。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【編織時空三:探究順序表與鏈表的數(shù)據(jù)之旅】

    【編織時空三:探究順序表與鏈表的數(shù)據(jù)之旅】

    鏈表OJ題 思路一:刪除頭結(jié)點時另做考慮(由于頭結(jié)點沒有前一個結(jié)點) 思路二:添加一個虛擬頭結(jié)點,刪除頭結(jié)點就不用另做考慮 思路:通過三個指針的操作,每次將當(dāng)前節(jié)點反轉(zhuǎn)并向前移動 ? 思路:頭插法 思路:快慢指針的前進(jìn)方向相同,且它們步伐的「差」是恒定

    2024年02月11日
    瀏覽(95)
  • 順序表與鏈表

    順序表與鏈表

    思維導(dǎo)圖: ? 順序表與鏈表都是兩種線性表,但是兩者之間又有著許多的不同。順序表是一種連續(xù)的空間,實際上就是數(shù)組。鏈表是不連續(xù)的空間,鏈表的空間是一塊一塊的開辟出來的。 兩者的優(yōu)點與缺點 : 順序表: 優(yōu)點: 1.順序表的空間是連續(xù)的,所以能夠支持下標(biāo)的

    2024年02月12日
    瀏覽(22)
  • 順序表與鏈表的區(qū)別

    目錄 一、順序表和鏈表的比較 順序表 優(yōu)點: 缺點: 鏈表 優(yōu)點 缺點 二、順序表和鏈表的區(qū)別 1.順序表和鏈表都具有增、刪、查、改功能,但算法復(fù)雜度卻不相同。 2、從數(shù)據(jù)元素存儲的內(nèi)存角度來看 三、順序表與鏈表選取方案 順序表的特點是邏輯上相鄰數(shù)據(jù)元素,物理存

    2024年02月08日
    瀏覽(563)
  • 《數(shù)據(jù)結(jié)構(gòu)與算法》之隊列與鏈表復(fù)習(xí)

    《數(shù)據(jù)結(jié)構(gòu)與算法》之隊列與鏈表復(fù)習(xí)

    我們在上一次學(xué)習(xí)了堆棧的數(shù)據(jù)結(jié)構(gòu)以后,可以了解到它是受限制的操作,比如我們操作只能在棧頂,現(xiàn)在我們要學(xué)習(xí)的東西叫做隊列,它也是受限制的一種數(shù)據(jù)結(jié)構(gòu),它的特點是隊頭只出數(shù)據(jù),而隊尾只入數(shù)據(jù), 它的結(jié)構(gòu)就和它的名字,像我們平時排隊一樣先來的人肯定要

    2024年02月08日
    瀏覽(31)
  • 【數(shù)據(jù)結(jié)構(gòu)】LinkedList與鏈表

    【數(shù)據(jù)結(jié)構(gòu)】LinkedList與鏈表

    上節(jié)課已經(jīng)熟悉了ArrayList的使用,并且進(jìn)行了簡單模擬實現(xiàn)。通過源碼知道,ArrayList底層使用數(shù)組來存儲元素: 由于其底層是一段連續(xù)空間,當(dāng) 在ArrayList任意位置插入或者刪除元素時,就需要將后序元素整體往前或者往后搬移,時間復(fù)雜度為O(n),效率比較低 ,因此A rrayLi

    2024年02月07日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu)—LinkedList與鏈表

    數(shù)據(jù)結(jié)構(gòu)—LinkedList與鏈表

    目錄 一、鏈表 1.?鏈表的概念及結(jié)構(gòu) 1. 單向或者雙向 2. 帶頭或者不帶頭 3. 循環(huán)或者非循環(huán) 二.LinkedList的使用 ?1.LinkedList概念及結(jié)構(gòu) 2. LinkedList的構(gòu)造 3.?LinkedList的方法 三. ArrayList和LinkedList的區(qū)別 ? ????????鏈表是一種 物理存儲結(jié)構(gòu)上非連續(xù) 存儲結(jié)構(gòu),數(shù)據(jù)元素的 邏輯

    2024年02月04日
    瀏覽(26)
  • 【數(shù)據(jù)結(jié)構(gòu)】順序表與ArrayList

    【數(shù)據(jù)結(jié)構(gòu)】順序表與ArrayList

    作者主頁: paper jie 的博客 本文作者:大家好,我是paper jie,感謝你閱讀本文,歡迎一建三連哦。 本文錄入于《JAVA數(shù)據(jù)結(jié)構(gòu)》專欄,本專欄是針對于大學(xué)生,編程小白精心打造的。筆者用重金(時間和精力)打造,將javaSE基礎(chǔ)知識一網(wǎng)打盡,希望可以幫到讀者們哦。 其他專欄

    2024年02月08日
    瀏覽(29)
  • 【數(shù)據(jù)結(jié)構(gòu)(二)】順序表與ArrayList

    【數(shù)據(jù)結(jié)構(gòu)(二)】順序表與ArrayList

    ?博主主頁: 33的博客? ?文章專欄分類:數(shù)據(jù)結(jié)構(gòu)? ??我的代碼倉庫: 33的代碼倉庫?? ?????? 關(guān)注我?guī)銓W(xué)更多數(shù)據(jù)結(jié)構(gòu)知識 在計算機(jī)科學(xué)中,數(shù)據(jù)結(jié)構(gòu)是處理和組織數(shù)據(jù)的方法和技術(shù)。順序表是一種常見的線性表數(shù)據(jù)結(jié)構(gòu),它基于數(shù)組實現(xiàn),提供了快速的隨機(jī)訪問能力

    2024年04月12日
    瀏覽(27)
  • 【數(shù)據(jù)結(jié)構(gòu)】線性表與順序表

    【數(shù)據(jù)結(jié)構(gòu)】線性表與順序表

    ? 作者:小胡_不糊涂 ?? 作者主頁:小胡_不糊涂的個人主頁 ?? 收錄專欄:淺談數(shù)據(jù)結(jié)構(gòu) ?? 持續(xù)更文,關(guān)注博主少走彎路,謝謝大家支持 ?? 線性表(linear list) 是n個具有相同特性的數(shù)據(jù)元素的有限序列。 它是一種在實際中廣泛使用的數(shù)據(jù)結(jié)構(gòu),常見的線性表:順序表

    2024年02月07日
    瀏覽(34)
  • 【數(shù)據(jù)結(jié)構(gòu)】鏈表與LinkedList

    【數(shù)據(jù)結(jié)構(gòu)】鏈表與LinkedList

    作者主頁: paper jie 的博客 本文作者:大家好,我是paper jie,感謝你閱讀本文,歡迎一建三連哦。 本文錄入于《JAVA數(shù)據(jù)結(jié)構(gòu)》專欄,本專欄是針對于大學(xué)生,編程小白精心打造的。筆者用重金(時間和精力)打造,將javaSE基礎(chǔ)知識一網(wǎng)打盡,希望可以幫到讀者們哦。 其他專欄

    2024年02月08日
    瀏覽(86)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包