之前完全靠自己的理解建立了一个单链表,但是思想并不怎么成熟,虽然是勉强做出来了,但是还是有很多地方自己把自己绕晕过去,所以过完年之后没那么多事儿了,就重新温习一遍上课时候使用的教材:李春葆的数据结构第四版。觉得自己应该把书上的数据结构都实现一遍,当然逻辑部分还是要学习一下,毕竟完全靠自己思考,有时会显得逻辑混乱。再一次拿起数据结构,感觉逻辑还是很容易理解的,之前学习的时候有什么感觉也记不住了,印象不怎么深,表明之前我也没认真看过这本书(这里自嘲一下) 。
好的,下面是代码部分,根据习惯,我还是编写的一个头文件:
//-----------------------------------【程序说明】----------------------------------------------
// 程序名称::LinearList
// 2016年2月 Create by arrstd
// 描述:李春葆的数据结构第四版,线性表的思考,c++入门式
//---------------------------------------------------------------------------------------------
#pragma once
#ifndef LINEARLIST
#define LINEARLIST
#include<iostream>
using namespace std;
//-----------------------------------------------------------
// 线性表之顺序表
#define MaxSize 50 //设置data的大小,这里和李春葆一样设置为50
//顺序表类
class SqList {
private:
int data[MaxSize]; //存放数据的数组
int length; //顺序表实际长度
public:
SqList();
void CreateList(int a[],int n); //创建顺序表,把一个数组内的数据放在顺序表中
bool ListEmpty(); //判断是否为空表
int ListLength(); //返回顺序表的长度
void DispList(); //输出顺序表内容
bool GetElem(int i,int &e); //得到位置为i的值,并赋值给e
int LocateElem(int e); //得到值为e的数据的位置,有多个相同的值时,这里只返回的一个值得位置
bool ListInsert(int i, int e); //在位置为i的地方插入值e
bool ListDelete(int i); //删除位置为i的值
};
SqList::SqList()
{
data[MaxSize] = { 0 };
length = 0;
}
void SqList::CreateList(int a[], int n)
{
for (int i = 0; i < n; i++)
{
this->data[i] = a[i];
}
this->length = n;
}
bool SqList::ListEmpty()
{
return(this->length == 0);
}
int SqList::ListLength()
{
return this->length;
}
void SqList::DispList()
{
for (int i = 0; i != this->length; i++)
{
cout << this->data[i] << " ";
}
cout << endl;
}
bool SqList::GetElem(int i, int &e)
{
if (i<1 || i>this->length)
return false;
e = this->data[i-1];
return true;
}
int SqList::LocateElem(int e)
{
int i = 0;
while (i < this->length && this->data[i] != e)
i++;
if (i >= this->length)
return 0;
else
return i + 1;
}
bool SqList::ListInsert(int i, int e)
{
if (i<1 || i>this->length + 1)
return false;
--i;
for (int j = this->length; j != i; j--)
{
this->data[j] = this->data[j - 1];
}
this->data[i] = e;
this->length++;
return true;
}
bool SqList::ListDelete(int i)
{
if (i<1 || i>this->length)
return false;
for (int j = --i; j != this->length - 1; j++)
{
this->data[j] = this->data[j + 1];
}
this->length--;
return true;
}
// 线性表之顺序表
//-----------------------------------------------------------
//-----------------------------------------------------------
// 线性表之链表
/**************************************单链表*************************************************/
class LinkList
{
private:
int data;
LinkList* next;
public:
void CreateListF(LinkList* &head ,int a[],int n); //头插法建立单链表
void CreateListR(LinkList* &head , int a[],int n); //尾插法建立单链表
int ListLength(LinkList* head); //返回单链表的实际长度
void DispList(LinkList* head); //输出单链表
};
void LinkList::CreateListF(LinkList* &head,int a[], int n)
{
head = new LinkList;
head->next = NULL;
for (int i = 0; i != n; i++)
{
LinkList* s = new LinkList;
s->data = a[i];
s->next = head->next;
head->next = s;
}
}
void LinkList::CreateListR(LinkList* &head, int a[], int n)
{
head = new LinkList;
LinkList *r = head, *s;
for (int i = 0; i != n; i++)
{
s = new LinkList;
s->data = a[i];
r->next = s;
r = s;
}
r->next = NULL;
}
int LinkList::ListLength(LinkList* head)
{
int n = 0;
LinkList* p = head;
while (p->next)
{
n++;
p = p->next;
}
return n;
}
void LinkList::DispList(LinkList* head)
{
LinkList* p = head->next;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
/**************************************双链表*************************************************/
class DLinkList
{
private:
int data;
DLinkList* prior;
DLinkList* next;
public:
void CreateDListF(DLinkList* &head, int a[], int n); //头插法建立双链表
void DispDList(DLinkList* head); //输出双链表
void CreateDListR(DLinkList* &head, int a[], int n); //尾插法建立双链表
};
void DLinkList::CreateDListF(DLinkList* &head, int a[], int n)
{
head = new DLinkList;
head->next = head->prior = NULL;
for (int i = 0; i != n; i++)
{
DLinkList* s = new DLinkList;
s->data = a[i];
s->next = head->next;
if (head->next)
{
head->next->prior = s;
}
head->next = s;
s->prior = head;
}
}
void DLinkList::CreateDListR(DLinkList* &head, int a[], int n)
{
head = new DLinkList;
DLinkList *s, *r = head;
for (int i = 0; i != n; i++)
{
s = new DLinkList;
s->data = a[i];
r->next = s;
s->prior = r;
r = s;
}
r->next = NULL;
}
void DLinkList:DispDList(DLinkList* head)
{
DLinkList* p = head->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
// 线性表之链表
//-----------------------------------------------------------
#endif // ! LINEARLIST
当然,线性表不是只有顺序表和单链表以及双链表,如果按照书上的内容的话还应该做有序表以及循环链表,其实最好实现一个具体的问题,但是我这里呢就先偷一下懒,其实链表这里我也没把增删改查等基本功能写完,只是把创建链表以及输出链表给做了,结合李春葆的思想,看着还是那么回事儿(哈哈[@@]),其他的还好,之前发的文章中有具体实现,再复杂一点的算法就需要结合具体问题了,虽然我也比较喜欢研究算法,但是这里还是先搁置一下比较好,不能整天都一直琢磨吧。
这里在vs2015里面测试通过,并没有什么问题(至少我自己没测出来),但是还是留下了一个疑惑:
int x[] = {1,2,3,4,5,6,7,8,9};
int n = sizeof(x) / sizeof(int);
DLinkList list;
DLinkList* p = &list;
list.CreateDListR(p, x, n);
list.DispDList(p);
如果我生成一个实例 list ,使用P指针只想 list ,但是list的内容依旧为空,这里还需要好好想一下,顺序表我是用this指针成功的避免这种情况,但是在链表这里,如果采用李春葆的思想的话,却是让人费解(当然,一般情况是我自己没想清楚,如果有热心人理解并开导我的话,我会非常感激!!!)