1. 程式人生 > >迴圈雙鏈表的C++實現

迴圈雙鏈表的C++實現



     

    迴圈雙鏈表通過指標將頭節點與尾節點也建立了與其他節點間相似的連線方式。這樣做之後,就淡化了連結串列中存在表頭與表尾的意義。因為事實上,連結串列中任意兩個相鄰節點之間的連線關係都是一樣的。我們將迴圈雙鏈表的資料結構表示成“圓圈”結構,如圖(箭頭均表示指標指向):

而一個單節點的迴圈雙鏈表可以看成該節點自連線形成的“圓圈”結構,如下圖所示:

       

即滿足條件:Single_Lists->previous= Single_Lists->next = Single_Lists

    於是,對於迴圈雙鏈表中的任意節點都可以同等看待,不存在特殊節點(頭節點、尾節點)。我們基於前面的雙鏈表結構,實現迴圈雙鏈表。

    在<List.h>標頭檔案裡宣告迴圈雙鏈表結構:

#include "list.h"

//迴圈的雙鏈表結構,包含一些常見的操作
#ifndef _List_H_
#define _List_H_

#include <iostream>

struct Double_Node{
	int element;  //節點儲存資訊可以根據需要修改!
	Double_Node* previous;
	Double_Node* next;
};

Double_Node* CreateLists(int X); //建立一個迴圈雙鏈表(此時只有一個節點)
void OutputLists(Double_Node* Lists); //輸出連結串列中所有元素的值
void DeleteLists(Double_Node* Lists); //刪除迴圈雙鏈表
Double_Node* Find(int X, Double_Node* Lists);   //從迴圈雙鏈表中查詢X
void Delete(int X, Double_Node* Lists);
void Insert(Double_Node* P, int X); //在節點P後面插入X
int GetNumofNodes(Double_Node* Lists); //返回節點總個數

#endif

然後,在<List.cpp>檔案裡實現迴圈雙鏈表操作(由於不存在特殊節點,部分操作可以簡化):

#include "list.cpp"

#include "list.h"
#include <assert.h>

Double_Node* CreateLists(int X)
{
	Double_Node* Lists = new Double_Node;
	Lists->element = X;
	Lists->previous = Lists->next = Lists; //單節點連結串列形成自迴圈
	return Lists;
}

void DeleteLists(Double_Node* Lists)  
{
	assert(Lists);
	Double_Node* P = Lists->next, *temp;
	Lists->next = P->previous = NULL;
	while(P!=Lists)  
	{  
		temp = P->next; 
        P->next = temp->previous = NULL;					
		delete P;  
		P = temp;  
	}
	delete Lists;
}  

Double_Node* Find(int X, Double_Node* Lists)
{
	assert(Lists);
	Double_Node* P = Lists;
	do{
		if(P->element == X)
			return P;
		else
			P = P->next;
	}while(P!=Lists);
	return NULL;
}

void Delete(int X, Double_Node* Lists)
{
	Double_Node* temp = Find(X,Lists); //如果沒找到X,則temp=NULL
	if(temp)
	{
		temp->previous->next = temp->next;
		temp->next->previous = temp->previous;
		temp->previous = temp->next = NULL;
		delete temp;
	}
}

void Insert(Double_Node* P, int X)
{
	assert(P);
	Double_Node* tempX = new Double_Node;
	tempX->element = X;
	tempX->previous = P;
	tempX->next = P->next;
	P->next->previous = tempX;	   
	P->next = tempX;
}

void OutputLists(Double_Node* Lists)
{
	assert(Lists);
	Double_Node* P = Lists;
	do{
		std::cout<<P->element<<"   ";
		P = P->next;
	}while(P!=Lists);
	std::cout<<std::endl;
}

int GetNumofNodes(Double_Node* Lists)
{
	assert(Lists);
	int count = 1;
	Double_Node* P = Lists->next;
	while(P!=Lists)
	{
         count++;
		 P = P->next;
	}
	return count;	
}
最後,同樣用一段main程式碼驗證一下:
#include <iostream>
#include "list.h"

using namespace std;

int main()
{
	int Data[10] = {1,3,4,6,0,2,5,8,12,13};
	Double_Node* Lists = CreateLists(1);
	Double_Node* P = Lists;
	for(int i=1;i<10;i++)
	{
		Insert(P,Data[i]);
		P = P->next;
	}
	cout<<"打印出迴圈雙鏈表的所有元素:\n";
	OutputLists(Lists);
	if(Find(8,P))
		cout<<"Find函式沒有問題!!\n";
	Delete(8,Lists);
	cout<<"Delete節點8後,再打印出(非迴圈)雙鏈表的所有元素:\n";
	OutputLists(Lists);
	cout<<"迴圈雙鏈表總節點數為:"<<GetNumofNodes(P)<<endl;
	DeleteLists(Lists);
	return 0;
}
結果如下: