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

C++_009_数据结构_线性表_间接寻址方式储存

2017-05-24 23:19 489 查看

代码开始前的闲谈

    1.本章在基础的顺序表功能上增加了 循环移动k位的函数、约瑟夫问题的求解函数,合并两个顺序表的函数。
    2 .如果线性表 首先重载了 cout<<,线性表的元素也重载了cout<<。.cout <<多次重载 可以用 static 或者 inline 来限制文件作用域  就不会 报重复定义的错了。

包括的主要知识点

    1.间接寻址方式顺序表的书写。
    2.循环移动k位的算法。
    3.约瑟夫问题的求解函数。

运行结构截图



头文件

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

template<class T>
class LinearList;

template<class T>
ostream& operator<<(ostream & os, LinearList<T> & a);

template<typename T>
void PrintList2(LinearList<T> & a);

typedef struct student
{
int ID;
char name[40];
friend ostream & operator<<(ostream & out, struct student & data)
{
out << "student ID:";
out << data.ID;
out << " name:";
out << data.name;
out << endl;
return out;
}
}student;

template<class T>
class LinearList
{
public:
LinearList();//无参数构造函数。
LinearList(int maxSize);
LinearList(T a[], int n);//n个数据的 构造函数。
LinearList(const LinearList& a);//深拷贝构造函数
~LinearList();//析构函数。

private:
T **Data;//
int Length;//总容量。
int Size;//当前容量。
public:
int GetLength();//获取线性表储存数据的个数。
int GetSize();//获取顺序表总分配空间。
T GetPos(int pos);//返回线性表的 第 pos 个数据。
void InsertObjInPos(T Obj, int pos);//在第 pos 个位置 插入Obj
T DeletePos(int pos);//删除第 pos 个位置的数据。
int Locate(T Obj);//查找 数据Obj 的位置。没有则返回 -1。
void PrintList1();
friend ostream& operator<< <>(ostream & os, LinearList<T>& a);//重载输出线性表
friend void PrintList2<>(LinearList<T> & a);//友元函数输出顺序表。
T SetPosToObj(int pos, T Obj);//把第 pos 个位置的数据改成 Obj
T *ToFirstAdd();//返回线性表首地址
void SetLength(int len);//设置线性表长度。
void RevListSeg(int form, int to);//从 form 到 to 位 倒置。
void LeftRotate(int k);//数据循环左移 k 位。
void Josephus(int m);//报数到 m 的人出圈。
LinearList<T> & operator =(const LinearList<T> & a);//深拷贝。
};

template<typename T>
ostream& operator<<(ostream & os, LinearList<T> & a)
{
for (int i = 0; i < a.Length; i++)
{
os << *(a.Data[i]) << " ";
}
os << '\n';
return os;
}

template<typename T>
void PrintList2(LinearList<T> & a)
{
for (int i = 0; i < a.Length; i++)
{
std::cout << *(a.Data[i]) << " ";
}
std::cout << '\n';
}

源文件

#include "stdafx.h"
#include "LinearList.h"

template<typename T>
LinearList<T>::LinearList()
{
Length = 0;
Size = 5;
Data = new T*[5];
}

template<class T>
LinearList<T>::LinearList(int maxSize)
{
Length = 0;
Size = 10;
Data = new T*[maxSize];
}

template<typename T>
LinearList<T>::LinearList(T a[], int n)
{
this->Length = n;
this->Size = n;
this->Data = new T*
;
if (this->Data == nullptr)
{
throw "LinearList (T a[] , int n) trapped!\n";
}

for (int i = 0; i < n; i++)
{
this->Data[i] = new T;
*(this->Data[i]) = a[i];
}
}

template<typename T>
LinearList<T>::LinearList(const LinearList & a)
{
this->Length=a.Length;
this->Size=a.Size;
this->Data = new T*[a.Size];
for (int i = 0; i < this->Length; i++)
{
this->Data[i] = new T;
*(this->Data[i])=*(a.Data[i]);
}
}

template<typename T>
LinearList<T>::~LinearList()
{
for (int i = 0; i < Length; i++)
{
delete [] (this->Data[i]);
}
delete [] this->Data;
Length = 0;
}

template<typename T>
int LinearList<T>::GetLength()
{
return this->Length;
}

template<class T>
int LinearList<T>::GetSize()
{
return Size;
}

template<typename T>
T LinearList<T>::GetPos(int pos)
{
return *(this->Data[pos]);
}

template<typename T>
void LinearList<T>::InsertObjInPos(T Obj, int pos)
{
if (pos > Length + 1 || pos<1)
{
throw "InsertObjInPos error! And mostly the position is too long or too short";
return;
}
this->Length++;
if(Length > Size)
{
Size += 10;
this->Data = (T **)realloc(this->Data, Size * sizeof(T));
if (this->Data == nullptr)
{
//throw exception();
throw "InsertObjInPos error! And mostly wrong in realloc";
}
}
T * temp=this->Data[Length - 1] = new T;
*temp = Obj;
for (int i = Length - 1; i >= pos; i--)
{
this->Data[i] = this->Data[i - 1];
}
this->Data[pos - 1] = temp;
}

template<typename T>
T LinearList<T>::DeletePos(int pos)
{
if (pos<1 || pos>this->Length)
{
throw "DeletePos error and mostly the position is wrong";
}
T temp = *(this->Data[pos - 1]);
T *p = this->Data[pos - 1];
for (int i = pos - 1; i < Length - 1; i++)
{
this->Data[i] = this->Data[i + 1];
}
delete p;
this->Data[Length - 1] = nullptr;
Length--;
return temp;
}

template<typename T>
int LinearList<T>::Locate(T Obj)
{
int pos = -1;
for (int i = 0; i < Length; i++)
{
if (*(this->Data[i]) == Obj)
{
//return i+1;
pos = i + 1;
return pos;
}
}
return pos;
}

template<typename T>
void LinearList<T>::PrintList1()
{
for (int i = 0; i < this->Length; i++)
{
std::cout << *(this->Data[i]) << ' ';
}
std::cout << endl;
}

template<typename T>
T LinearList<T>::SetPosToObj(int pos, T Obj)
{
if (pos<1 || pos>this - Length + 1)
{
throw "DeletePos error and mostly the position is wrong";
}
if (pos == Length + 1)
{
Length++;
this->Data[Length - 1] = new T;
*(this->Data[pos - 1]) = Obj;
}
*(this->Data[pos - 1]) = Obj;
return T();
}

template<typename T>
T * LinearList<T>::ToFirstAdd()
{
return this->Data[0];
}

template<typename T>
void LinearList<T>::SetLength(int len)
{
this->Length = len;
}

template<typename T>
void LinearList<T>::RevListSeg(int form, int to)
{
if (form < 1 || form>Length || to<1 || to>Length)
{
throw "RevListSeg() error!";
}
T *temp;
for (int i = 0; i <= (to - form) / 2; i++)
{
temp = Data[form - 1 + i];
Data[form - 1 + i] = Data[to - 1 - i];
Data[to - 1 - i] = temp;
}
}

template<class T>
void LinearList<T>::LeftRotate(int k)
{
RevListSeg(1, k);
RevListSeg(k + 1, Length);
RevListSeg(1, Length);
}

template<class T>
void LinearList<T>::Josephus(int m)
{
int s = 0;//出圈的位置。
for (int n = Length; n >= 2; n--)
{
s = (s + m-1) % n;
cout << "After delete " << *Data[s]<<": ";
DeletePos(s+1);
cout << *this;
}
cout << "delete position " << m << " the result is " << *this;
}

template<typename T>
LinearList<T> & LinearList<T>::operator=(const LinearList<T> & a)
{
if (this->Length != 0)
{
for (int i = 0; i < Length; i++)
{
delete[] this->Data[i];
}
delete[] this->Data;
}
this->Length = a.Length;
this->Size = a.Size;
this->Data = new T*[a.Size];
for (int i = 0; i < this->Length; i++)
{
this->Data[i] = new T;
*(this->Data[i]) = *(a.Data[i]);
}
return *this;
}

用于测试的主函数

// 线性表_间接寻址.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include"LinearList.cpp"
//#include"Student.h"
#include<iostream>
using namespace std;

int main()
{

int test[10] = { 2,4,6,8,10,12,14,16,18,20 };
LinearList<int> a(test, 10);

std::cout << "构造函数后顺序表为:" << endl;
a.PrintList1();//第一种方法输出。

std::cout << "在第1个位置插入99" << endl;
a.InsertObjInPos(99, 1);
PrintList2(a);//第二种方法输出。

std::cout << "在第12个位置插入88" << endl;
a.InsertObjInPos(88, 12);
cout << a;//重载输出。

std::cout << "查找 数据 3 的位置:" << a.Locate(3) << endl;
std::cout << "查找到数据 4 并删除后输出:";
a.DeletePos(a.Locate(4));
cout << a;//再来一个重载输出。其实重载输出还有其他的写法。我这里用了 <> 来写。下一章我会用其他的写法实现重载。

cout << "输出顺序表数组首地址元素:";
std::cout << a.ToFirstAdd()[0]<< endl;

cout << "倒置 2-6位后:";
a.RevListSeg(2, 6);
cout<<a;

cout << "循环左移 3 位后:";
a.LeftRotate(3);
cout << a;

cout << endl << " 另一个顺序表:";
int test2[10] = { 1,2,3,4,5,6,7,8,9,10 };
LinearList<int> b(test2, 8);
cout << b;
cout << "报数到 3 的出圈:";
b.Josephus(3);

cout << "拷贝 a 表 到 c 表 :";
LinearList<int> c(a);
cout << a;

cout << "operator = 拷贝c:";
LinearList<int> d;

b282
d = c;
cout << d;
cout << "operator = 拷贝b:";
d = b;
cout << d;

cout << "元素为两个学生结构的线性表:";
student e[3];
e[0].ID=111;
e[1].ID=222;
e[2].ID=333;
strcpy_s(e[0].name, 40, "aaa");
strcpy_s(e[1].name, 40, "bbb");
strcpy_s(e[2].name, 40, "ccc");
LinearList<student> f(e, 2);
cout << f;

cout << "在第三个位置插入一个学生结构:"<<endl;
f.InsertObjInPos(e[2], 3);
cout << f;
cout << "删除第二个元素:"<<endl;
f.DeletePos(2);
cout << f;
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息