C++_010_数据结构_静态链表_静态双链表普通存储版

代码开始前的闲谈

    培训笔记写着写着想出书了。《计算机协会常规培训_C/C++ 第一版》。

主要内容

1.静态链表(模拟链表)的写法。
2.静态链表的插入、删除、初始化等操作。
3.重载operator []。
4.这里只写静态循环双链表,和双链表的普通存储方式,至于用间接寻址方式的的同 上一个博客《C++_009_数据结构_线性表_间接寻址方式储存》的原理一样。这里不在赘述。

运行截图:


静态链表头文件

#pragma once
#include<iostream>
#include<ostream>
#include<istream>
using namespace std;
#define MaxSize 100

template<class T>
class StaticList;

template<typename T>
void PrintList(StaticList<T> & a);

template<class T>
class StaticList
{
public:
	StaticList();//构成循环双链表。
	StaticList(int n);//构成非循环双链表。
	StaticList(T a[],int Length);//含参构造函数。循环双链表。
	~StaticList();//
	T Data[MaxSize]; //数据部分。Data[0]是首个,不存储数据,只作为找到链表的入口。
	int Next[MaxSize];//后指针。
	int Front[MaxSize];//前指针。
	int Length;//链表中总数据个数。

	int NullList;//空闲指针的头。
	int NullListNext[MaxSize];//空闲指针的链。

	friend ostream& operator<<(ostream & out, const StaticList<T> & a);//正向输出。
	friend void PrintList<>(StaticList<T> & a);//逆向输出链表。

	int GetLength();//获取当前链表总长度。
	T GetPos(int pos);//获取链表往前数第 Pos 个数据。
	T operator [] (int pos);//获取往后数第 pos 个数据。

	void InsertObjToPos(T Obj, int pos);//在 pos 个位置 插入 数据Obj
	T DeletePos(int pos);//删除 第 Pos 个数据。
	int Locate(T Obj);//查找 Obj的 位置。没找到返回 -1.
	T *ToFirstAdd();//返回数据的首地址。
};

template<typename T>
inline ostream& operator <<(ostream & out,StaticList<T> & a)
{
	int add =a.Next[0];
	for (int i = 0; i < a.Length; i++)
	{
		out << a.Data[add]<<" ";
		add = a.Next[add];
	}
	out << std::endl;
	return out;
}

template<typename T>
void PrintList(StaticList<T> & a)
{
	int pos = a.Front[0];
	for (int i = 0; i < a.Length; i++)
	{
		cout << a.Data[pos];
		cout<<" ";
		pos = a.Front[pos];
	}
	cout <<endl;
}

静态链表源文件

#include "stdafx.h"
#include "StaticList.h"

template<typename T>
StaticList<T>::StaticList()//构成循环双链表。
{
	Next[0] = 0;//指向自身,构成循环链表
	Front[0] = 0;//指向自身,构成循环链表
	Length = 0;
	NullList = 1;
	for (int i = 1; i < MaxSize; i++)
	{
		NullListNext[i] = i + 1;
	}
	NullListNext[MaxSize-1] = -1;
}

template<typename T>
StaticList<T>::StaticList(int n)//构成非循环双链表
{
	Next[0] = -1;
	Front[0] = -1;
	Length = 0;
	NullList = 1;
	for (int i = 1; i < MaxSize; i++)
	{
		NullListNext[i] = i + 1;
	}
	NullListNext[MaxSize-1] = -1;
}

template<typename T>
StaticList<T>::StaticList(T a[], int Length) //含参构造函数。循环双链表。
{
	if (Length > MaxSize - 1)
	{
		throw "Arrays is too long !\n";
	}
	Next[0] = 1;
	for (int i = 1; i <= Length; i++)
	{
		Data[i] = a[i-1];
		Next[i] = i + 1;
		Front[i] = i - 1;
	}
	Front[0] = Length;
	Next[Length] = 0;
	this->Length = Length;
	NullList = Length + 1;
	for (int i = NullList; i < MaxSize; i++)
	{
		NullListNext[i] = i + 1;
	}
	NullListNext[MaxSize - 1] = -1;
}

template<typename T>
StaticList<T>::~StaticList()//析构函数
{
	Next[0] = -1;
	Front[0] = -1;
	Length = 0;
}

template<class T>
int StaticList<T>::GetLength()//返回链表长度
{
	return this->Length;
}

template<typename T>
T StaticList<T>::GetPos(int pos)//获取链表往前数第 Pos 个数据。
{
	while (pos > Length)
	{
		pos -= Length;
	}
	int add = 0;
	for (int i = 0; i < pos; i++)
	{
		add = Front[add];
	}
	return Data[add];
}

template<typename T>
T StaticList<T>::operator[](int pos)//获取往后数第 pos 个数据。
{
	while (pos > Length)
	{
		pos -= Length;
	}
	int add = 0;
	for (int i = 0; i < pos; i++)
	{
		add = Next[add];
	}
	return Data[add];
}

template<class T>
void StaticList<T>::InsertObjToPos(T Obj, int pos)//在 pos 个位置 插入 数据Obj
{
	if (pos<1 || pos>Length + 1)
	{
		throw "InsertObjToPos Error!\n";
	}
	if (this->Length > MaxSize - 1)
	{
		throw "can't use InserObjToPos(),because the StaticList is too long\n";
	}
	int add =0;//找应插入的位置
	for (int i = 0; i < pos; i++)
	{
		add = Next[add];
	}
	//找空闲链表。
	int NullAdd = NullList;
	NullList = NullListNext[NullAdd];
	Data[NullAdd] = Obj;
	Next[NullAdd] = add;
	Front[NullAdd] = Front[add];
	Next[Front[add]] = NullAdd;
	Front[add] = NullAdd;
	
	Length++;
}

template<class T>
T StaticList<T>::DeletePos(int pos)//删除 第 Pos 个数据。
{
	if (pos<1 || pos>Length + 1)
	{
		throw "InsertObjToPos Error!\n";
	}
	int add = 0;//找应删除的位置,并把空间返回给空链表。
	for (int i = 0; i < pos; i++)
	{
		add = Next[add];
	}
	Next[Front[add]] = Next[add];
	Front[Next[add]] = Front[add];
	Front[add] = -1;
	//找空链表。
	Next[add] = NullList;
	NullListNext[add] = NullList;
	NullList = add;
	Length--;
	return Data[add];
}

template<class T>
int StaticList<T>::Locate(T Obj)//查找 Obj的 位置。没找到返回 -1.
{
	int add = Next[0];
	int res = -1;
	for (int i = 0; i < Length; i++)
	{
		if (Obj == Data[add])
		{
			return add;
		}
		else
		{
			add = Next[add];
		}
	}
	return res;
}

template<class T>
T * StaticList<T>::ToFirstAdd()//返回数据的首地址。
{
	return Data;
}

主函数

// 静态链表_普通版.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include"StaticList.cpp"
using namespace std;

int main()
{
	int test[7] = { 3,6,9,11,12,13,14};
	StaticList<int> a(test,7);
	cout << "原始链表:";
	cout << a;
	cout << "倒序输出:";
	PrintList(a);
	cout << "正数第三个元素:";
	cout << a[3]<<endl;
	cout << "倒数第三个元素:";
	cout << a.GetPos(3)<<endl<<endl;

	a.InsertObjToPos(999, 1);
	cout << "在第1个位置 插入 999 后的链表:"<<endl;
	cout << a<<endl;
	
	a.InsertObjToPos(888, 6);
	cout << "在第6个位置 插入 888 之后的链表:"<<endl;
	cout << a<<endl;
	
	a.DeletePos(1);
	cout << "删除第一个位置之后的链表:" << endl;
	cout << a<<endl;

	a.DeletePos(8);
	cout << "删除第 8 个 位置之后的链表:" << endl << a;
	
	cout << "数据存储的首地址:" << endl;
	cout << a.ToFirstAdd();

	getchar();
return 0;}
 
  

	

猜你喜欢

转载自blog.csdn.net/wang_huizhang/article/details/72718640