循环双链表_混合链表(双链表中储存顺序表)
链表和线性表各有优缺点,把二者混合,就能充分利用二者的优点。双链表中的结点存储的是顺序表,把两种线性表混合使用。
包含的主要知识点
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;
}