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




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