代码开始前的闲谈
培训笔记写着写着想出书了。《计算机协会常规培训_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;}