1. 程式人生 > >C++實現雙向連結串列

C++實現雙向連結串列

下面就是我們雙向連結串列的基本原理。

這裡我們插入程式碼案例:標頭檔案DoubleLink.h

#ifndef DOUBLE_LINK_HXX
#define DOUBLE_LINK_HXX

#include <iostream>
using namespace std;
//一個節點
template<class T> 
struct DNode 
{
public:
	T value;
	DNode *prev;
	DNode *next;
public:
	DNode() { }
	DNode(T t, DNode *prev, DNode *next) {
		this->value = t;
		this->prev  = prev;
		this->next  = next;
	}
};
//雙向連結串列基本操作
template<class T> 
class DoubleLink 
{
public:
	DoubleLink();
	~DoubleLink();

	int size();//大小
	int is_empty();//判斷是否為空

	T get(int index);//獲取節點
	T get_first();//獲取首節點
	T get_last();//獲取尾節點

	int insert(int index, T t);
	int insert_first(T t);
	int append_last(T t);

	int del(int index);
	int delete_first();
	int delete_last();

private:
	int count;
	DNode<T> *phead;
private:
	DNode<T> *get_node(int index);
};

template<class T>
DoubleLink<T>::DoubleLink() : count(0)
{
	// 建立“表頭”。注意:表頭沒有儲存資料!
	phead = new DNode<T>();
	phead->prev = phead->next = phead;
	// 設定連結串列計數為0
	//count = 0;
}

// 解構函式
template<class T>
DoubleLink<T>::~DoubleLink() 
{
	// 刪除所有的節點
	DNode<T>* ptmp;
	DNode<T>* pnode = phead->next;
	while (pnode != phead)
	{
		ptmp = pnode;
		pnode=pnode->next;
		delete ptmp;
	}

	// 刪除"表頭"
	delete phead;
	phead = NULL;
}

// 返回節點數目
template<class T>
int DoubleLink<T>::size() 
{
	return count;
}

// 返回連結串列是否為空
template<class T>
int DoubleLink<T>::is_empty() 
{
	return count==0;
}

// 獲取第index位置的節點
template<class T>
DNode<T>* DoubleLink<T>::get_node(int index) 
{
	// 判斷引數有效性
	if (index<0 || index>=count)
	{
		cout << "get node failed! the index in out of bound!" << endl;
		return NULL;
	}

	// 正向查詢
	if (index <= count/2)
	{
		int i=0;
		DNode<T>* pindex = phead->next;
		while (i++ < index) {
			pindex = pindex->next;
		}

		return pindex;
	}

	// 反向查詢
	int j=0;
	int rindex = count - index -1;
	DNode<T>* prindex = phead->prev;
	while (j++ < rindex) {
		prindex = prindex->prev;
	}

	return prindex;
}

// 獲取第index位置的節點的值
template<class T>
T DoubleLink<T>::get(int index) 
{
	return get_node(index)->value;
}

// 獲取第1個節點的值
template<class T>
T DoubleLink<T>::get_first() 
{
	return get_node(0)->value;
}

// 獲取最後一個節點的值
template<class T>
T DoubleLink<T>::get_last() 
{
	return get_node(count-1)->value;
}

// 將節點插入到第index位置之前
template<class T>
int DoubleLink<T>::insert(int index, T t) 
{
	if (index == 0)
		return insert_first(t);

	DNode<T>* pindex = get_node(index);
	DNode<T>* pnode  = new DNode<T>(t, pindex->prev, pindex);
	pindex->prev->next = pnode;
	pindex->prev = pnode;
	count++;

	return 0;
}

// 將節點插入第一個節點處。
template<class T>
int DoubleLink<T>::insert_first(T t) 
{
	DNode<T>* pnode  = new DNode<T>(t, phead, phead->next);
	phead->next->prev = pnode;
	phead->next = pnode;
	count++;

	return 0;
}

// 將節點追加到連結串列的末尾
template<class T>
int DoubleLink<T>::append_last(T t) 
{
	DNode<T>* pnode = new DNode<T>(t, phead->prev, phead);
	phead->prev->next = pnode;
	phead->prev = pnode;
	count++;

	return 0;
}

// 刪除index位置的節點
template<class T>
int DoubleLink<T>::del(int index) 
{
	DNode<T>* pindex = get_node(index);
	pindex->next->prev = pindex->prev;
	pindex->prev->next = pindex->next;
	delete pindex;
	count--;

	return 0;
}

// 刪除第一個節點
template<class T>
int DoubleLink<T>::delete_first() 
{
	return del(0);
}

// 刪除最後一個節點
template<class T>
int DoubleLink<T>::delete_last() 
{
	return del(count-1);
}

#endif

得意接下來就放入DlinkTest.cpp

#include <iostream>
#include "DoubleLink.h"
using namespace std;

// 雙向連結串列操作int資料
void int_test()
{
	int iarr[4] = {10, 20, 30, 40};//定義一個數組

	cout << "\n開始測試 int資料" << endl;
	// 建立雙向連結串列
	DoubleLink<int>* pdlink = new DoubleLink<int>();

	pdlink->insert(0, 20);        // 將 20 插入到第一個位置
	pdlink->append_last(10);    // 將 10 追加到連結串列末尾
	pdlink->insert_first(30);    // 將 30 插入到第一個位置

	// 雙向連結串列是否為空
	cout << "is_empty()=" << pdlink->is_empty() <<endl;
	// 雙向連結串列的大小
	cout << "size()=" << pdlink->size() <<endl;

	// 列印雙向連結串列中的全部資料
	int sz = pdlink->size();
	for (int i=0; i<sz; i++)
		cout << "pdlink("<<i<<")=" << pdlink->get(i) <<endl;
}


int main()
{
	int_test();        // 演示向雙向連結串列操作“int資料”。
	system("pause");
	return 0;
}
上面程式碼親自敲的,並且執行成功。可複製直接使用。