1. 程式人生 > >雙向迴圈連結串列C++實現(完整版)

雙向迴圈連結串列C++實現(完整版)

#include<iostream>
using namespace std;

/*
*節點類
*/
struct DCNode
{
  int data;
  DCNode * prior;
  DCNode * next;
};
/*
*連結串列類
*/
struct DCList
{
	DCList()
	{
		size = 0;
	}
	size_t size;//記錄節點數的個數
	DCNode * head;//指向連結串列的頭結點
};

/*
*分配一個節點,並給該節點的資料域賦值,預設值為0;
*/
DCNode * MakeNode(int t=0)
{
	DCNode * p = (DCNode *)malloc(sizeof(DCNode));
	p->data = t;
	return p;
}

//初始化一個空的雙向迴圈連結串列
void InitDCList(DCList &list)
{
	//分配一個頭結點
	DCNode * p = MakeNode();
	list.head = p;
	list.size = 0;
	p->next = p;
	p->prior = p;
}

//釋放所指向的節點
void FreeNode(DCNode * p)
{
	delete p;
}

//清空一個線性表
void clear(DCList &list)
{
	DCNode * p = list.head;
	p = p->next;
	while(p!= list.head)
	{  
		DCNode * p1 = p->next;
		delete p;
		p = p1;
	}
	list.size = 0;
}

//將s所指向的節點插入到連結串列的第一個節點之前
bool InsFirst(DCList &list,DCNode * s)
{
	
	s->next = list.head->next;
	list.head->next->prior = s;
	list.head->next = s;
	s->prior = list.head;
	list.size++;
	return true;
}

//刪除連結串列中的第一個節點並以q指標返回
bool DelFirst(DCList &list,DCNode *  & q)
{
	if(list.head->next==list.head)//如果連結串列為空
	{
		q = 0;
		return false;
	}
	q = list.head->next;
	list.head->next->next->prior = list.head;
	list.head->next = list.head->next->next;
	list.size--;
	return true;
}

//將s所指向的節點串接在連結串列的最後一個節點之後
bool Append(DCList &list,DCNode * s)
{
	s->prior = list.head->prior;
	s->next = list.head;
	list.head->prior->next = s;
	list.head->prior = s;
	list.size++;
	return true;
}

//刪除連結串列中的尾節點,並以指標q返回
bool Remove(DCList &list,DCNode * & q)
{
	if(list.head->next==list.head)//如果連結串列為空
	{
		q = 0;
		return false;
	}
	q = list.head->prior;
	list.head->prior->prior->next = list.head;
	list.head->prior = list.head->prior->prior;
	list.size--;
	return true;
}

//將s所指向的節點插入連結串列中p所指向的節點之前
bool InsBefore(DCList &list,DCNode * p,DCNode * s)
{
	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
	 if(p1==p)//找到該連結串列中是否存在p所指向的節點
	 {
		 s->next = p;
		 s->prior = p->prior;
		 p->prior->next = s;
		 p->prior = s;
		 list.size++;
	     return true;
	 }
	  p1 = p1->next;
	}
	//沒找到
	return false;
}

//將s所指向的節點插入連結串列中p所指向的節點之後
bool InsAfter(DCList &list,DCNode * p,DCNode * s)
{
	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
	 if(p1==p)//找到該連結串列中是否存在p所指向的節點
	 {
		 s->next = p->next;
		 s->prior = p;
		 p->next->prior = s;
		 p->next = s;
		 list.size++;
	     return true;
	 }
	 p1 = p1->next;
	}
	//沒找到
	return false;
}

//判斷連結串列是否為空
bool Empty(DCList &list)
{
	if(list.size==0)
	return  true;
	else
	return false;

}

//返回連結串列的長度
int GetLength(DCList &list)
{
	return list.size;
}

//返回連結串列中第i個節點的指標
DCNode * LocatePos(DCList &list,int i)
{
	if(i<=0&&i>(int)list.size ) return 0;//如果不存在第i個節點則返回一個0指標
	int n = 0;
	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
	 n++;
	 if(n==i)//找到
	 {
		return p1;
	 }
	 p1 = p1->next;
	}
	return 0;
}

//在連結串列中查詢第一個元素值與t相等的節點指標
DCNode * LocateElem(DCList &list,int t)
{
	if(list.head->next==list.head)//如果連結串列為空
	{
		return 0;
	}
	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
		if(p1->data==t)//找到
	 {
		return p1;
	 }
	 p1 = p1->next;
	}
	return 0;
}

//在連結串列中查詢第一個元素值與t滿足compare函式關係的節點指標
DCNode * LocateElem(DCList &list,int t,bool (* compare)(int ,int))
{
	if(list.head->next==list.head)//如果連結串列為空
	{
		return 0;
	}
	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
		if((*compare)(p1->data,t))//找到了
	 {
		return p1;
	 }
	 p1 = p1->next;
	}
	return 0;
}

//依次對連結串列中的每一個元素呼叫visit函式,一旦visit函式呼叫失敗,則整個操作失敗
bool ListTraverse(DCList &list,bool (*visit)(int &))
{

	DCNode * p1 = list.head->next;
	while(p1!=list.head)
	{
		if(!(*visit)(p1->data))//找到了
	 {
		return false;
	 }
	 p1 = p1->next;
	}
	return true;
}

//合併兩個雙向迴圈連結串列
DCList & MergeList(DCList &list1,DCList &list2)
{
	if(Empty(list1))
	{
		return list2;
	}
	if(Empty(list2))
	{
		return list1;
	}
	list1.head->prior->next = list2.head->next;
	list2.head->next->prior = list1.head->prior;
	list1.head->prior = list2.head->prior;
	list2.head->prior->next = list1.head;
	return list1;
}

//判斷是否一個數為偶數
bool judge(int a,int b)
{
	if(a%b==0) return true;
	return false;
}

bool visit(int & t)
{
	t = t+1;
	return true;
}

int main()
{
//建立並初始化一個空的雙向迴圈連結串列
	DCList myList;
	InitDCList(myList);

//在連結串列的尾端新增元素
	//現分配一個節點
	DCNode * s = MakeNode(1);
	Append(myList,s);
	s = MakeNode(3);
	Append(myList,s);
	s = MakeNode(5);
	Append(myList,s);
	s = MakeNode(7);
	Append(myList,s);

//遍歷該連結串列,並輸出該連結串列的元素個數
	DCNode * p1 = myList.head->next;
	cout<<"新建一個雙向連結串列,並初始化元素值為1,3,5,7"<<endl;
	while(p1!=myList.head)
	{
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	}
	cout<<endl;
	cout<<"連結串列的元素個數為:"<<GetLength(myList)<<endl;

//在連結串列的第一個資料節點之前插入兩個元素

	s = MakeNode(9);
	InsFirst(myList,s);
	s = MakeNode(0);
	InsFirst(myList,s);
	 cout<<"在連結串列的第一個資料節點之前插入兩個元素值為0,9的節點:"<<endl;
	 p1 = myList.head->next;
	while(p1!=myList.head)
	{
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	}
	cout<<endl;

//刪除連結串列中的第一個節點和尾節點 
	 cout<<"刪除的第一個節點"<<endl;
	 if(DelFirst(myList,s))
	 {
		 cout<<"被刪除的第一個節點資料為:"<<s->data<<endl;
	 }
	  p1 = myList.head->next;
	while(p1!=myList.head)
	{
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	}
	cout<<endl;
	//釋放被刪除的節點空間
	 FreeNode(s);
	 cout<<"刪除的尾節點"<<endl;
	if( Remove(myList,s) )
	{
		 cout<<"被刪除的尾節點資料為:"<<s->data<<endl;
	}
	 p1 = myList.head->next;
	while(p1!=myList.head)
	{
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	}
	cout<<endl;
	//釋放被刪除的節點空間
	FreeNode(s);

//在第二個節點之前插入元素
	 p1 = LocatePos(myList,2);
	 cout<<"第二個節點資料為:"<<p1->data<<endl;
	 s = MakeNode(11);
	 InsBefore(myList,p1,s);
	 cout<<"在第二個節點之前插入一個元素值為11的新節點:"<<endl;
	 p1 = myList.head->next;
	 while(p1!=myList.head)
	 {
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	 }
	 cout<<endl;

//在第二個節點之後插入元素
	 s = MakeNode(16);
	 p1 = LocatePos(myList,2);
	 InsAfter(myList,p1,s);
	 cout<<"再在第二個節點之後插入一個元素值為16的新節點:"<<endl;
	 p1 = myList.head->next;
	 while(p1!=myList.head)
	 {
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	 }
	 cout<<endl;

//查詢第一個元素值為4的倍數的節點
	 p1 = LocateElem(myList,4,judge);
	 cout<<"找到第一個元素值為4的倍數的節點資料為:"<<p1->data<<endl;

//將連結串列中所有的元素值都增加1
	 ListTraverse(myList,visit);
	 cout<<"將連結串列中所有的元素值都增加1:"<<endl;
	 p1 = myList.head->next;
	 while(p1!=myList.head)
	 {
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	 }
	 cout<<endl;

//新建一個元素值為1,3,9的連結串列
	 DCList myList2;
	InitDCList(myList2);

//在連結串列的尾端新增元素
	//現分配一個節點
	 s = MakeNode(1);
	Append(myList2,s);
	s = MakeNode(3);
	Append(myList2,s);
	s = MakeNode(9);
	Append(myList2,s);

//遍歷該連結串列,並輸出該連結串列的元素個數
	 cout<<"新建一個元素值為1,3,9的連結串列:"<<endl;
    p1 = myList2.head->next;
	while(p1!=myList2.head)
	{
		cout<<p1->data<<"  ";
	 p1 = p1->next;
	}
	cout<<endl;

//合併兩個連結串列
	 myList = MergeList(myList,myList2);
	 cout<<"合併兩個連結串列:"<<endl;
	 p1 = myList.head->next;
	 while(p1!=myList.head)
	 {
		cout<<p1->data<<"  ";
	    p1 = p1->next;
	 }
	 cout<<endl;
	 cout<<"最後清空myList連結串列!"<<endl;
	 clear(myList);
}