溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++怎么用數(shù)組模擬鏈表

發(fā)布時間:2022-01-12 18:06:07 來源:億速云 閱讀:147 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章的內(nèi)容主要圍繞C++怎么用數(shù)組模擬鏈表進行講述,文章內(nèi)容清晰易懂,條理清晰,非常適合新手學習,值得大家去閱讀。感興趣的朋友可以跟隨小編一起閱讀吧。希望大家通過這篇文章有所收獲!

前言

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

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

1.單鏈表

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

C++怎么用數(shù)組模擬鏈表

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

Q: 那么,如何用數(shù)組來實現(xiàn)它呢?

A: 方法如下

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

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

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

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

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

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

#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.雙鏈表

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

C++怎么用數(shù)組模擬鏈表

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

它的實現(xiàn)方法如下:

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

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

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

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é)點。刪除結(jié)點與插入結(jié)點同理,我就不多贅述了。

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

輸出鏈表。可以選擇輸出方向,這里是從左往右輸出。

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++怎么用數(shù)組模擬鏈表”這一問題有一定的了解,快去動手實踐吧,如果想了解更多相關(guān)知識點,可以關(guān)注億速云網(wǎng)站!小編會繼續(xù)為大家?guī)砀玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI