您的位置:首页 > 编程语言 > C语言/C++

C++线性表链式存储结构

2015-12-11 21:15 381 查看
本来想要在头结点的数据域存放链表长度,结果后来这样反而出了一些麻烦
#include <iostream>

using namespace std;

#define MAXSIZE 123

typedef int ElemType;//为复杂的声明定义简单的别名

struct Node
{
ElemType date;
Node *next;
Node(ElemType elem);
};
Node::Node(ElemType elem)//节点的构造函数里对数据域赋值,不用在新建节点之后再赋值
{
date=elem;
next=NULL;
}

class LinkList
{
public:
LinkList();
~LinkList();
bool GetElem(int i,ElemType &elem);//获取第i个元素
bool InsertBetween(int i,ElemType elem);//中间某位置插入
bool InsertAfterHead(ElemType elem);//头结点之后插入
bool DeleteNode(int i,ElemType &elem);//删除结点并返回结点数据域
ElemType GetListLength();//获得链表长度,其实就是头结点数据域
void* GetHead();//获得头结点
bool DestroyLinklist();//销毁链表
private:
Node *at_head;
};

bool LinkList::DestroyLinklist()
{
Node *p=at_head->next;

for(;p;)
{
at_head->next=p->next;
delete p;//只是释放指针指向的内存,指针本身并没有被删除
p=at_head->next;
}
delete at_head;
return true;
}

void* LinkList::GetHead()
{
return at_head;
}

LinkList::LinkList()
{
at_head=new Node(0);
}

ElemType LinkList::GetListLength()
{
return at_head->date;
}

bool LinkList::InsertBetween(int i,ElemType elem)
{
if(i>at_head->date)
return false;
int j=0;
Node *p=at_head;//让p指向头结点
while(p&&j<i-1)//寻找第i-1个结点
{
p=p->next;
++j;
}
if(!p||j>i-1)//执行完上面的循环,p要么指向第i-1个结点,要么指向链表最后一个节点
return false;
Node *pNode=new Node(elem);
pNode->next=p->next;
p->next=pNode;
++(at_head->date);
return true;
}

bool LinkList::InsertAfterHead(ElemType elem)//这个就不是很必要了,已经修改上面的插入算法可以插入在头结点后面
{
Node *p=new Node(elem);
p->next=at_head->next;
at_head->next=p;
++(at_head->date);
return true;
}

bool LinkList::GetElem(int i,ElemType &elem)
{
int j=1;//记录目前指向第几个
Node *p=at_head->next;
while (p&&j<i)
{
p=p->next;
++j;
}//p指向最后一个节点
if(p==NULL||j>i)//需要>i吗?
return false;
elem=p->date;
return true;
}

bool LinkList::DeleteNode(int i,ElemType &elem)
{
int j=0;
Node *p=at_head,*p2;
while (p&&j<i-1)//真的需要吗???
{
p=p->next;
++j;
}
if(!p->next||j>i-1)//不明白为什么要第二个条件
return false;
p2=p->next;
p->next=p2->next;
delete p2;
--(at_head->date);
return true;
}

void MergeList(LinkList &list1,LinkList &list2,LinkList &list3)//函数内部链表长度发生了变化,要恢复正确数值
{
Node *p1=((Node*)list1.GetHead())->next;
Node *p2=((Node*)list2.GetHead())->next;
((Node*)list3.GetHead())->next=p1;
Node *p3=(Node*)list3.GetHead();
while (p1&&p2)
{
if(p1->date<p2->date)
{
p3->next=p1;p3=p1;p1=p1->next;
--((Node*)list1.GetHead())->next;
}
else
{
p3->next=p2;p3=p2;p2=p2->next;
}
}
p1?p3->next=p1:p3->next=p2;
((Node*)list3.GetHead())->date=((Node*)list1.GetHead())->date+((Node*)list2.GetHead())->date;
((Node*)list1.GetHead())->next=NULL;
((Node*)list2.GetHead())->next=NULL;
}

LinkList::~LinkList()
{
}

void main()
{
LinkList list1,list2,list3;
for(int i=20;i>0;----i)
{
list1.InsertAfterHead(i);
}
for(int i=19;i>0;----i)
{
list2.InsertAfterHead(i);
}
ElemType testValue;
ElemType test;
//list1.DeleteNode(5,test);
//list1.InsertBetween(18,100);
for(int i=1;i<=list1.GetListLength();++i)
{
list1.GetElem(i,testValue);
cout<<testValue<<" ";
}
cout<<"\n";
for(int i=1;i<=list2.GetListLength();++i)
{
list2.GetElem(i,testValue);
cout<<testValue<<" ";
}
cout<<"\n";
MergeList(list1,list2,list3);
for(int i=1;i<=list3.GetListLength();++i)
{
list3.GetElem(i,testValue);
cout<<testValue<<" ";
}
list1.DestroyLinklist();
list2.DestroyLinklist();
list3.DestroyLinklist();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 链表