代碼開始前的閒談
培訓筆記寫着寫着想出書了。《計算機協會常規培訓_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;}