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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值