C++_011_數據結構_循環雙鏈表_混合鏈表

循環雙鏈表_混合鏈表(雙鏈表中儲存順序表)

     鏈表和線性表各有優缺點,把二者混合,就能充分利用二者的優點。雙鏈表中的結點存儲的是順序表,把兩種線性表混合使用。

包含的主要知識點

1.混合線性表的寫法。
2.深拷貝構造函數,重載 = 運算符。
3.混合鏈表輸出重載。
4.模板線性表。

運行截圖


主函數

// MixedTable.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include"Link.cpp"

int main()
{
	int temp[6] = { 1,2,3,4,5,6 };
	Link<int> a(temp,6);
	cout << "原始鏈表:"<<a;
	cout << "倒敘輸出:";
	print<int>(a);
	Link<int> A(a);
	cout << "拷貝鏈表:" << A;
	cout << "拷貝鏈表倒敘:";
	print<int>(A);

	a.Insert(999, 3);
	cout << endl << "在第 3 個位置插入 999 :" << a<<endl;

	cout << "在第8個位置 插入 666 :" << a;
	try
	{
		a.Insert(666, 8);
	}
	catch (char s[])
	{
		cout << s<<endl;
	}
	
	a.Insert(666, 7);
	cout << "在第 7個位置 插入 666 :" << a;

	a.Add(333);
	cout << "在尾部插入 333 :" << a << endl;

	a.Delete(9);
	cout << "刪除第 9 個數據:" << a ;

	a.Delete(1);
	cout << "刪除第 1 個數據:" << a << endl;

	a.Add(222);
	cout << "在尾部插入 222 :" << a<<endl;

	a.Delete(a.GetLength());
	cout << "刪除尾部數據:" << a << endl;

	cout<<"查找數據 2 的位置 :"<<a.Locate(2)<<endl<<"查找數據 999 的位置 :"<<a.Locate(999)<<endl;

	Link<int> c = a;
	cout << "=深拷貝函數:" << c;
	cout << "=深拷貝倒序:";
	print<int>(c);

	cout << endl << "第三個數據爲:" << c[3] << endl<<endl;

	Linear d[2];
	d[0].length = d[1].length=10;
	for (int i = 0; i < 10; i++)
	{
		d[0].block[i] = 1;
		d[1].block[i] = 2;
	}
	Link<Linear> e(d, 2);
	cout << "混合鏈表:"<< endl <<e;

	LINEAR<double> f[2];
	f[0].length = f[1].length = 5;
	for (int i = 0; i < 5; i++)
	{
		f[0].block[i] = 3.3;
		f[1].block[i] = 4.3;
	}
	Link<LINEAR<double>> g(f, 2);
	cout << "模板混合鏈表" << endl << g;
	getchar();
    return 0;
}

線性表類頭文件

#pragma once
#include<ostream>
#include<iostream>
using namespace std;

template<typename T>
class Link;

template<typename T>
ostream& operator <<(ostream & out, Link<T> &a);//正序輸出。
template<typename T>
void print(Link<T> & a);//逆序輸出。

struct Linear
{
	int length;
	int block[20];
	friend ostream& operator << (ostream & out, Linear &a);
};
ostream& operator <<(ostream & out, Linear &a);


template<typename T>
struct LINEAR
{
	int length;
	T block[20];
	friend ostream& operator << <>(ostream & out, LINEAR<T> &a);
};
template<typename T>
ostream& operator <<(ostream & out, LINEAR<T> &a);

template<typename T>
struct Node
{
	T Data;
	Node<T> * Next;
	Node<T> * Front;
};


template<typename T>
class Link
{
public:
	Link();//構造循環雙鏈表
	Link(T a[],int length);//構造循環雙鏈表;
	Link(int length,T a[]);//構造雙鏈表,不循環。
	Link(Link<T> &a);//深拷貝函數。
	~Link();//析構函數。釋放內存。

private:
	Node<T> * First;//頭指針。指向第一個數據塊。第一個數據塊不存信息。
	Node<T> * Tail;//尾指針。方便操作。
	int Length;//鏈表長度。

public:
	T Insert(T Obj,int pos);//插入 Obj 到 pos 個位置。存數據的第一個位置爲 1 。
	T Add(T Obj);//在尾部插入 Obj;
	int GetLength();//返回鏈表總長度。
	T Delete(int pos);//刪除 pos 個 位置的數據。

	int Locate(T Obj);//查找 Obj ,未找到返回 -1。找到返回該位置。

	Link<T> & operator =(Link<T> &a);//深拷貝函數。
	T operator[](int pos);//返回第 pos 個數據。

	friend ostream& operator << <>(ostream & out, Link<T> &a);//正序輸出。
	friend void print<>(Link<T> & a);//逆序輸出。
};

template<typename T>
ostream& operator <<(ostream & out, Link<T> &a)//正序輸出。
{
	Node<T> *temp = a.First->Next;
	for (int i = 0; i < a.Length; i++)
	{
		out << temp->Data << " ";
		temp = temp->Next;
	}
	out << endl;
	return out;
}

template<typename T>
void print(Link<T> & a)//逆序輸出。
{
	Node<T> *temp = a.First->Front;
	for (int i = 0; i < a.Length; i++)
	{
		cout << temp->Data << " ";
		temp = temp->Front;
	}
	cout << endl;
}

/*
*這裏必須用內聯。才能避免函數名相同。
*/
inline ostream& operator << (ostream & out, Linear &a)
{
	for (int i = 0; i < a.length; i++)
	{
		out << a.block[i] << " ";
	}
	out << endl;
	return out;
}

template<typename T>
inline ostream& operator << (ostream & out, LINEAR<T> &a)
{
	for (int i = 0; i < a.length; i++)
	{
		out << a.block[i] << " ";
	}
	out << endl;
	return out;
}

線性表類 源文件

#include "stdafx.h"
#include "Link.h"

template<typename T>
Link<T>::Link()//構造循環雙鏈表
{
	Node<T> * NewData = new Node<T>;
	NewData->Next = NewData;
	NewData->Front = NewData;
	First = NewData;
	Tail = NewData;
	Length = 0;
}

template<typename T>
Link<T>::Link(T a[], int length)
{
	Node<T> * NewData = new Node<T>;
	First = NewData;
	Tail = NewData;
	NewData->Front = NewData;
	NewData->Next = NewData;
	for (int i = 0; i < length; i++)
	{
		NewData = new Node<T>;
		NewData->Data = a[i];
		NewData->Front = Tail;
		NewData->Next = First;
		Tail->Next = NewData;
		Tail = NewData;
		First->Front = Tail;
	}
	Length = length;
}

template<typename T>
Link<T>::Link(int length, T a[])
{
	Node<T> * NewData = new Node<T>;
	First = Tail = NewData;
	NewData->Front = nullptr;
	NewData->Next = nullptr;
	for (int i = 0; i < length; i++)
	{
		NewData = new Node<T>;
		NewData->Data = a[i];
		NewData->Front = Tail;
		Tail->Next = NewData;
		Tail = NewData;
	}
	Tail->Next = nullptr;
	Length = length;
}

template<typename T>
Link<T>::Link(Link<T>& a)
{
	Node<T> * NewData = new Node<T>;
	this->First = this->Tail = NewData;
	Node<T> *cursor = a.First->Next;
	for (int i = 0; i < a.Length; i++)
	{
		NewData = new Node<T>;
		NewData->Data = cursor->Data;
		NewData->Front = Tail;
		Tail->Next = NewData;
		Tail = NewData;
		cursor = cursor->Next;
	}
	First->Front = NewData;
	NewData->Next = First;
	this->Length = a.Length;
}

template<typename T>
Link<T>::~Link()
{
	Node<T> * WaitDelete = First;
	while (Length > 0)
	{
		First = First->Next;
		delete WaitDelete;
		WaitDelete = First;
		Length--;
	}
	delete WaitDelete;
}

template<typename T>
T Link<T>::Insert(T Obj, int pos)
{
	if (pos > this->Length||pos<1)
	{
		throw "Insert(T Obj,int pos), the pos is wrong.\n";
	}
	Node<T> *cursor = First;
	for (int i = 0; i < pos; i++)
	{
		cursor = cursor->Next;
	}
	Node<T> *NewData = new Node<T>;
	NewData->Data = Obj;
	NewData->Next = cursor;
	NewData->Front = cursor->Front;
	cursor->Front->Next = NewData;
	cursor->Front = NewData;
	this->Length++;
	if (pos == Length)
	{
		Tail = NewData;
	}
	return Obj;
}

template<typename T>
T Link<T>::Add(T Obj)
{
	Node<T> *NewData = new Node<T>;
	NewData->Data = Obj;
	NewData->Front = Tail;
	NewData->Next = First;
	Tail->Next = NewData;
	First->Front = NewData;
	this->Length++;
	return Obj;
}

template<typename T>
int Link<T>::GetLength()
{
	return this->Length;
}

template<typename T>
T Link<T>::Delete(int pos)
{
	if (pos<1 || pos>Length)
	{
		throw "Delete(int pos) wrong positin.\n";
	}
	Node<T> *cursor = First;
	for (int i = 0; i < pos; i++)
	{
		cursor = cursor->Next;
	}
	T Obj = cursor->Data;
	cursor->Front->Next = cursor->Next;
	cursor->Next->Front = cursor->Front;
	
	if (pos == Length)
	{
		Tail = cursor->Front;
	}
	delete cursor;
	this->Length--;
	return Obj;
}

template<typename T>
int Link<T>::Locate(T Obj)
{
	Node<T> *cursor = First;
	int res = -1;
	for (int i = 0; i < Length; i++)
	{
		cursor = cursor->Next;
		if (cursor->Data == Obj)
		{
			res = i+1;
			return res;
		}
	}
	return res;
}

template<typename T>
Link<T>& Link<T>::operator=(Link<T>& a)
{
	Link<T> res();
	Node<T> *cursor = a.First->Data;
	Node<T> *NewData;
	for (int i = 0; i < a.Length; i++)
	{
		NewData = new Node<T>;
		NewData->Data = cursor->Data;
		cursor->Front = res.Tail;
		res.Tail->Next = NewData;
		res.Tail = NewData;
	}
	NewData->Next = First;
	First->Front = NewData;
	return res;
}

template<typename T>
T Link<T>::operator[](int pos)
{
	if (pos<1 || pos>Length)
	{
		throw "operator[pos] pos is wrong.\n";
	}
	Node<T> *cursor = this->First;
	for (int i = 0; i < pos; i++)
	{
		cursor = cursor->Next;
	}
	return cursor->Data;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章