循環雙鏈表_混合鏈表(雙鏈表中儲存順序表)
鏈表和線性表各有優缺點,把二者混合,就能充分利用二者的優點。雙鏈表中的結點存儲的是順序表,把兩種線性表混合使用。
包含的主要知識點
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;
}