最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++如何用數組模擬鏈表

 更新時間:2022年01月12日 14:27:19   作者:Kicamon  
大家好,本篇文章主要講的是C++如何用數組模擬鏈表,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下

前言

鏈表是指由一系列儲存在非連續(xù)儲存空間 結點組成的儲存結構。每個結點由兩部分組成:一是儲存元素的數據域,一是儲存下一個節(jié)點地址的指針域。用數組模擬鏈表可以十分清晰明了地理解這一定義。

在這里,我們簡單地介紹一下單鏈表和雙鏈表兩種鏈表以及用數組模擬實現它們的方式。

1.單鏈表

單鏈表是指針方向單向的鏈表,即a結點的指針域儲存著b結點的地址,而b結點的指針域內沒有儲存a結點的地址。在訪問時,可以由a到b訪問,而不能由b到a訪問。

單鏈表

如圖可以清晰地看到,各個結點的指向都是單向的。

Q: 那么,如何用數組來實現它呢?

A: 方法如下

在k結點右側插入元素x。先將x賦值給該節(jié)點的數據域(e[idx]),然后將k結點的指針域賦值給該結點的指針域,最后將k結點的指針域儲存的地址改為該節(jié)點的地址。

void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx++;
}
刪除k結點指向的結點。這里所指的刪除,是將k的指向改為該結點的指向。原本為a -> b -> c,改為a -> c,b結點依然存在,只是沒有其他結點指向它,也就無法通過鏈表訪問它,我們認為它就再鏈表上被刪除了。
void remove(int k)
{
    ne[k] = ne[ne[k]];
}

讀取鏈表。讀取鏈表只用注意一點,在用單指針掃描時不是將指針位置右移,而是將指針移動到該結點指向的位置。

for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
cout << endl;

主要的操作就是如此,下邊看看完整代碼:

這是較為經典的寫法,我個人認為有些麻煩,head不必單獨拿出來寫一個函數。但是有助于理解。

#include<iostream>
using namespace std;

const int M = 1e5 + 10;

int m, k, x, idx, head;
int e[M], ne[M];

void init()
{
    head = -1, idx = 0;
}

void add_head(int x)
{
    e[idx] = x;
    ne[idx] = head;
    head = idx++;
}

void remove(int k)
{
    ne[k] = ne[ne[k]];
}

void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx++;
}

int main()
{
    init();

    cin >> m;
    while (m--)
    {
        char op;
        cin >> op;

        if (op == 'H')
        {
            cin >> x;
            add_head(x);
        }
        else if (op == 'D')
        {
            cin >> k;
            if (!k) head = ne[head];
            remove(k - 1);
        }
        else
        {
            cin >> k >> x;
            add(k - 1, x);
        }
    }

    for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
    cout << endl;

    return 0;
}

這種寫法稍微簡便一些,用a[0]替代head。

#include<iostream>
using namespace std;

const int M = 1e5 + 10;

int m, k, x, idx, head;
int e[M], ne[M];

void init()
{
    ne[0] = -1, idx = 1;
}

void remove(int k)
{
    ne[k] = ne[ne[k]];
}

void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx++;
}

int main()
{
    init();

    cin >> m;
    while (m--)
    {
        char op;
        cin >> op;

        if (op == 'H')
        {
            cin >> x;
            add(0, x);
        }
        else if (op == 'D')
        {
            cin >> k;
            if (!k) head = ne[head];
            remove(k);
        }
        else
        {
            cin >> k >> x;
            add(k, x);
        }
    }

    for (int i = ne[0]; i != -1; i = ne[i]) cout << e[i] << ' ';
    cout << endl;

    return 0;
}

2.雙鏈表

雙鏈表顧名思義就是指針方向雙向的鏈表。

雙鏈表

可以看到除了頭尾他們的指針都是雙向的。

它的實現方法如下:

創(chuàng)建開始和結束結點。0表示開始,1表示結束,互相指向,在插入時直接往中間插入即可。

void init()
{
	r[0] = 1, l[1] = 0;
	idx = 2;
}

插入結點。雙鏈表插入結點的方法與單鏈表相同,但是操作要稍微復雜一些,這是在k結點右邊插入一結點的代碼。它要顧及結點左右的結點指向,對于兩邊都要操作。面臨在k結點左邊插入一結點時,不必單獨在寫一個函數,而改成在l[k]結點的右邊插入一個結點。

void add(int k, int x)
{
	a[idx] = x;
	r[idx] = r[k], l[idx] = l[r[k]];
	l[r[k]] = idx, r[k] = idx;
	idx++;
}

刪除節(jié)點。刪除結點與插入結點同理,我就不多贅述了。

void remove(int k)
{
	r[l[k]] = r[k];
	l[r[k]] = l[k];
}

輸出鏈表??梢赃x擇輸出方向,這里是從左往右輸出。

for (int i = r[0]; i != 1; i = r[i])cout << a[i] << ' ';
	cout << endl;

以下是完整代碼:

#include<iostream>
using namespace std;

const int N = 1e5 + 10;

int a[N], l[N], r[N];
int idx;
int m;

void init()
{
	r[0] = 1, l[1] = 0;
	idx = 2;
}

void add(int k, int x)
{
	a[idx] = x;
	r[idx] = r[k], l[idx] = l[r[k]];
	l[r[k]] = idx, r[k] = idx;
	idx++;
}

void remove(int k)
{
	r[l[k]] = r[k];
	l[r[k]] = l[k];
}

int main()
{
	init();
	cin >> m;
	while (m--)
	{
		int k, x;
		string op;
		cin >> op;
		if (op == "L")
		{
			cin >> x;
			add(0, x);
		}
		else if (op == "R")
		{
			cin >> x;
			add(l[1], x);
		}
		else if (op == "D")
		{
			cin >> k;
			remove(k + 1);
		}
		else if (op == "IL")
		{
			cin >> k >> x;
			add(l[k + 1], x);
		}
		else if (op == "IR")
		{
			cin >> k >> x;
			add(k + 1, x);
		}
	}

	for (int i = r[0]; i != 1; i = r[i])cout << a[i] << ' ';
	cout << endl;
	return 0;
}

總結

到此這篇關于C++如何用數組模擬鏈表的文章就介紹到這了,更多相關C++數組模擬鏈表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mac OS X 10.8 中編譯APUE(Unix環(huán)境高級編程)的源代碼過程

    Mac OS X 10.8 中編譯APUE(Unix環(huán)境高級編程)的源代碼過程

    這篇文章主要介紹了Mac OS X 10.8 中編譯APUE(Unix環(huán)境高級編程)的源代碼過程,對于用MAC學習Unix環(huán)境高級編程的同學會有些作用,需要的朋友可以參考下
    2014-09-09
  • C語言聯合體類型的實現

    C語言聯合體類型的實現

    聯合體也是一種構造數據類型,和結構體類型一樣,它也是由各種不同類型的數據組成,本文主要介紹了C語言聯合體類型的實現,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • QT打包發(fā)布全流程(圖文教程)

    QT打包發(fā)布全流程(圖文教程)

    本文主要介紹了QT打包發(fā)布全流程,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • 基于C語言實現shell指令的詳解

    基于C語言實現shell指令的詳解

    本篇文章是對C語言實現shell指令的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++深入講解初始化列表的用法

    C++深入講解初始化列表的用法

    這篇文章主要介紹了C++成員初始化列表,除了可以使用構造函數對類成員進行初始化之外,C++還提供了另外一種初始化的方法,叫做成員初始化列表。下面來看看文章的詳細吧,需要的朋友可以參考一下
    2022-04-04
  • 基于C語言掃雷游戲的設計與實現

    基于C語言掃雷游戲的設計與實現

    大家好,本篇文章主要講的是基于C語言掃雷游戲的設計與實現,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • C++實現LeetCode(39.組合之和)

    C++實現LeetCode(39.組合之和)

    這篇文章主要介紹了C++實現LeetCode(39.組合之和),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • C語言判斷一個數是否是2的冪次方或4的冪次方

    C語言判斷一個數是否是2的冪次方或4的冪次方

    本文中我們來看一下如何用C語言判斷一個數是否是2的冪次方或4的冪次方的方法,并且判斷出來是多少次方,需要的朋友可以參考下
    2016-06-06
  • C語言線性表之雙鏈表詳解

    C語言線性表之雙鏈表詳解

    這篇文章主要為大家詳細介紹了C語言線性表之雙鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 數據結構與算法 排序(冒泡,選擇,插入)

    數據結構與算法 排序(冒泡,選擇,插入)

    這篇文章主要介紹了數據結構與算法 排序(冒泡,選擇,插入)的相關資料,這里對冒泡,選擇和插入都做有實例,需要的朋友可以參考下
    2017-07-07

最新評論

会理县| 苏州市| 临澧县| 大安市| 台南市| 沧州市| 忻州市| 镇赉县| 鹿泉市| 吉木萨尔县| 安化县| 巢湖市| 鱼台县| 仁布县| 澎湖县| 莒南县| 婺源县| 子洲县| 泌阳县| 曲周县| 理塘县| 桦川县| 黑山县| 屯留县| 祁阳县| 墨竹工卡县| 马鞍山市| 安图县| 开封市| 乌兰县| 沙河市| 洛浦县| 凤冈县| 英德市| 喜德县| 禹城市| 集贤县| 翼城县| 札达县| 桦川县| 喀喇|