双向链表的实现

《系统程序元成长计划》开头,要求大家先写个双向链表的程序,要求花1~3天时间完成这个任务,然后再往下阅读。看来数据结构还是很重要的:)今天我就实现一个简单的双向链表程序吧。


首先定义数据节点,类名就叫CNode吧。定义如下:

class CNode
{
public:
CNode* prenode;
CNode* nextnode;
int Item;
};

这个很简单,不用再解释了。然后定义双向链表类,名字就叫DList吧,定义如下:

class DList
{
private:
UINT NumberOfNode;//记录链表中节点的个数
CNode* phead;//链表头指针
CNode* ptail;//链表尾指针
public:
DList(void);
public:
~DList(void);
void InsertNode(int);//在链表中插入一个节点
void DeleteNode(int);//在链表中删除一个节点
void ShowList();//显示链表中所有元素
const UINT GetNumberOfNode() const {return NumberOfNode;}//得到链表中元素个数
void SetNumberOfNode(int Num) {NumberOfNode=Num;}//写入链表中元素个数
};

然后是DList的实现,代码如下:

DList::DList(void)
{
phead=NULL;
ptail=NULL;
NumberOfNode=0;
}


DList::~DList(void)
{
}


void DList::InsertNode(int InsertItem)
{
CNode* NewNode=new CNode;
NewNode->Item=InsertItem;
if (GetNumberOfNode()==0)//链表还没有创建
{
phead=ptail=NewNode;
NewNode->prenode=NULL;
NewNode->nextnode=NULL;
SetNumberOfNode(1);
return;
}
if (GetNumberOfNode()==1)
{
if (InsertItem<=phead->Item)//该元素应该插入到链表首
{
NewNode->nextnode=phead;
NewNode->prenode=NULL;
phead->prenode=NewNode;
phead=phead->prenode;

else//该元素应该插入到链表末
{
NewNode->nextnode=NULL;
NewNode->prenode=ptail;
ptail->nextnode=NewNode;
ptail=ptail->nextnode;
}
SetNumberOfNode(GetNumberOfNode()+1);
return;
}
//链表中至少有两个元素的情况
CNode* ptemp;//用于记录当前的指针位置
ptemp=phead;//初始化为链表头
while (ptemp!=ptail)
{
if (InsertItem<=ptemp->Item)
{
if (ptemp==phead)//插入链表头
{
NewNode->nextnode=phead;
NewNode->prenode=NULL;
phead->prenode=NewNode;
phead=phead->prenode;
}
else//插入链表中间
{
NewNode->nextnode=ptemp;
NewNode->prenode=ptemp->prenode;
ptemp->prenode->nextnode=NewNode;
ptemp->prenode=NewNode;
}
break;
}
ptemp=ptemp->nextnode;
}
if (ptemp==ptail)
{
if (InsertItem<=ptemp->Item)//插入最后一个元素之前
{
NewNode->nextnode=ptemp;
NewNode->prenode=ptemp->prenode;
ptemp->prenode->nextnode=NewNode;
ptemp->prenode=NewNode;

else//插入链表末
{
NewNode->nextnode=NULL;
NewNode->prenode=ptail;
ptail->nextnode=NewNode;
ptail=ptail->nextnode;
}
}
SetNumberOfNode(GetNumberOfNode()+1);
NewNode=NULL;
return;
}
void DList::DeleteNode(int DeleteItem)
{
if (GetNumberOfNode()==0)
{
cout<<"链表中没有元素!"<<endl;
getchar();
return;
}
CNode* ptemp=phead;
while(ptemp!=ptail)
{
if (ptemp->Item==DeleteItem)
{
if (ptemp==phead)//删除头节点
{
phead=phead->nextnode;
phead->nextnode->prenode=NULL;
ptemp->nextnode=NULL;
free(ptemp);
ptemp=NULL;

else//删除中间节点
{
ptemp->prenode->nextnode=ptemp->nextnode;
ptemp->nextnode->prenode=ptemp->prenode;
ptemp->prenode=NULL;
ptemp->nextnode=NULL;
free(ptemp);
ptemp=NULL;
}
SetNumberOfNode(GetNumberOfNode()-1);
break;
}
ptemp=ptemp->nextnode;
}
if (ptemp==ptail)
{
if (ptemp->Item==DeleteItem)//删除末节点
{
ptemp->prenode->nextnode=NULL;
ptail=ptemp->prenode;
ptemp->prenode=NULL;
free(ptemp);
ptemp=NULL;
SetNumberOfNode(GetNumberOfNode()-1);

else
{
cout<<"您要删除的元素不存在!!"<<endl;
getchar();
}
}
return;
}
void DList::ShowList()
{
if (GetNumberOfNode()==0)
{
cout<<"链表为空!!"<<endl;
getchar();
return;
}
CNode* ptemp=phead;
while(ptemp!=ptail)
{
cout<<ptemp->Item<<" ";
ptemp=ptemp->nextnode;
}
cout<<ptemp->Item<<endl;
cout<<"链表中共有"<<GetNumberOfNode()<<"个元素!"<<endl;
}


这些代码很简单,没什么多说的。这两个类完成后,就可以考虑主程序了,代码如下:

int _tmain(int argc, _TCHAR* argv[])
{
DList MyList;
cout<<"请输入链表中的元素,以-1结束"<<endl;
while (1)
{
int insertitem;
cin>>insertitem;
if (insertitem==-1)
{
break;

else
{
MyList.InsertNode(insertitem);
}
}
getchar();//为了去除最后一个回车
cout<<"您输入链表中的元素从小到大为:"<<endl;
MyList.ShowList();
int casetemp;
while(1)
{
int insertitem;
int deleteitem;
bool Isexit=false;
cout<<"请选择您要进行的操作:"<<endl;
cout<<"1--在链表中插入一个元素"<<endl;
cout<<"2--在链表中删除一个元素"<<endl;
cout<<"3--显示当前链表中的所有元素"<<endl;
cout<<"-1--退出当前程序"<<endl;
cin>>casetemp;
switch (casetemp)
{
case 1:
cout<<"请输入您要插入的元素:"<<endl;
cin>>insertitem;
MyList.InsertNode(insertitem);
break;
case 2:
cout<<"请输入您要删除的元素:"<<endl;
cin>>deleteitem;
MyList.DeleteNode(deleteitem);
break;
case 3:
MyList.ShowList();
break;
case -1:
exit(1);
default:
cout<<"您选择的操作不存在!!"<<endl;
}
}
return 0;
}


大功告成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值