您的位置:首页 > 理论基础 > 数据结构算法

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

2017-06-16 20:41 351 查看

代码开始前的闲谈

    培训笔记写着写着想出书了。《计算机协会常规培训_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;}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息