这篇文章我给大家介绍用C++语言实现单向链表
大家可以把代码复制到自己的编译器里,运行一下。,首先建立三个文件main.cpp ChainList.h ChainList.cpp
(其中的注释及讲解都在代码里.废话不多说,直接上代码。)
1,ChainList.h 文件
#pragma once
struct Node
{
int data;
Node* pNext;
};
class ChainList
{
public:
//构造函数
ChainList ();
//返回链表的长度
int getlength ();
//在pos位置插入da这个数据,使da成为第pos个数据
void insertData (int pos,int da);
//依次插入,
void pushBack (int dat);
//打印链表数据
void printList ();
//删除数据da
void deleteData (int da);
//析构函数
~ChainList ();
private:
//找到da数据并返回 目标数据的位置,这个借口不必向外部提供,所以把它设为private
int findData (int da);
private:
Node* head;
int length;
};
2. ChainList.cpp 文件
#include "ChainList.h"
#include<iostream>
using namespace std;
//构造函数
ChainList::ChainList ()
{
//node节点的默认值为-3,和nullptr
Node* pNew = new Node { -3,NULL };
this->length = 0;//长度为零
head = pNew;//把构造好的头结点赋给head,一个链表只有一个头结点
}
//返回链表的长度
int ChainList::getlength ()
{
return this->length;//直接return就好了
}
//根据位置插入数据,成功返回true
void ChainList::insertData (int pos,int da)
{
//情况一
if ( pos > this->length )//如果输入的pos太大,则把它当做最后一个数据,也就是在this->length插入da
{
pos = this->length;
}
//情况二
else if ( pos == this->length ){//如果pos恰好等于链表的长度的话,就相当于在链表的最后面插入da
pushBack (da);
return;
}
//情况三
Node* pNew = new Node { da,NULL };//新建一个节点放数据da
Node* previous = head,* next = head->pNext;
for ( int i = 0; i < pos-1; i++ )
previous = previous->pNext;//找到pos位置之前的一个节点
Node* tmp = previous->pNext;//要删除的节点tmp
next = previous->pNext->pNext;//next是pos之后的那一个节点
previous->pNext = pNew;//安排previous,next,pNew 三个节点的指向关系
pNew->pNext = next;
tmp->pNext = nullptr;//把tmp的pNext指针指向空
delete tmp;//把tmp申请的内存空间释放
}
//依次向后插入数据
void ChainList::pushBack (int dat)
{
Node* tp = head;//由头节点开始遍历
for ( int i = 0; i < this->length; i++ )
{
tp = tp->pNext;
}//循环结束后tp就指向最后一个节点了
Node* pNew = new Node { dat,NULL };
tp->pNext = pNew;//tp指向新节点pNew,那么pNew就是最后一个节点了
this->length++;//别忘了链表的长度要加1
}
//找到数据并返回 目标数据的位置
int ChainList::findData (int da)
{
Node* tp = head;
for ( int i = 0; i < this->length; i++ )//遍历链表,找到数据和da一样的节点,并且返回该节点在链表的位置
{
if(tp->data==da){
return i;
}
else
tp = tp->pNext;
}
/*为什么要再判断一次呢,因为要查找的数据是最后一个的时候,那么当i=(this->length)-1的时候,
判断tp->data是否等于da,答案是不等于,所以执行了else里面的语句,之后i++,跳出循环,
少判断了一次i=this->length的情况,所以要补上一次判断*/
if ( tp->data==da )
return this->length;
else
return -1;//遍历整个链表都找不到的话,就返回-1
}
//打印链表的数据
void ChainList::printList ()
{
Node* tmp = head;
if ( tmp==nullptr )//如果链表为空,那么提示出这句话
{
cout << "该链表为空" << endl;
return;
}
for ( int i = 0; i < this->length; i++ )//依次遍历并且打印
{
tmp = tmp->pNext;//先移到下一个,因为头结点是构造链表的时候默认的值,我们用不到,头结点相当于一个摆设,只负责链表入口的作用
cout <<tmp->data << " ";
}
cout << endl;
}
//删除da这个数据
void ChainList::deleteData (int da)
{
if ( da== -3 )//情况一,如果是-3,这说明删除的是头结点
{
cout << "不能删除链表的头结点" << endl;
return;
}
int pos2 = findData (da);//找到这个数据在链表里面是第几号
//情况二,链表里面没有da这个数据
if ( pos2 == -1 )//没找到的时候返回-1
{
cout << "=======对不起:没找到该数据 " << da<<"=======" << endl;
return ;
}
//情况三,要删除的数据是该链表的最后一个节点
else if ( pos2 == this->length )
{
Node* tmp = head;
for ( int i = 0; i < pos2; i++ )
{
tmp = tmp->pNext;
}
tmp->pNext = NULL;
}
//情况四,删除的是链表中普通的一个节点(不是头结点,也不是尾节点)
else{
Node* previous = head,* next = nullptr;
for ( int i = 0; i < pos2-1; i++ )
{
previous = previous->pNext;
}
Node* tmp = previous->pNext;//tmp是目标节点
next = previous->pNext->pNext;//找到目标节点的前后两个节点
previous->pNext = next;
delete tmp;
}
this->length--;
return;
}
ChainList::~ChainList ()
{
ChainList::~ChainList ()
{
if ( head==NULL )//如果链表的头节点为空的话,那么直接return;
{
return;
}
Node* tmp = head;//这就好比一个清洁组长(tmp2)带着一个清洁工(tmp)开始清洁卫生,
//tmp2指到哪里,tmp就清洁哪里
Node* tmp2 = head->pNext;
while ( tmp2 )//只要tmp2有地方指,tmp就有地方打扫
{
delete tmp;
tmp = tmp2;
tmp2 = tmp2->pNext;
}//最后tmp2没地方指了(指向NULL),退出循环..
delete tmp;//虽然tpm2没有地方指了,但是还得删除一次tmp,此时tmp指向的是最后一个节点
head = NULL;//释放完了head指针指向的空间,把head指针指向空
length = 0;// 析构结束之后,链表的长度也设为零
}
}
3,main.cpp
#include<iostream>
#include "ChainList.h"
using namespace std;
void t5 ()
{
ChainList cl;
cl.pushBack (17);
cl.pushBack (10);
cl.pushBack (4);
cl.pushBack (15);
cl.pushBack (13);
cl.pushBack (11);
cout << "链表的长度为:" << cl.getlength () << endl;
cout << "打印链表数据:"; cl.printList (); cout << endl;
cl.deleteData (4);
cout << "------------------------\n";
cout << "链表的长度为:" << cl.getlength () << endl;
cout << "打印链表数据:"; cl.printList (); cout << endl;
cl.insertData (3,100);
cout << "------------------------\n";
cout << "链表的长度为:" << cl.getlength () << endl;
cout << "打印链表数据:"; cl.printList (); cout << endl;
cl.deleteData (11);
cout << "------------------------\n";
cout << "链表的长度为:" << cl.getlength () << endl;
cout << "打印链表数据:"; cl.printList (); cout << endl;
cl.insertData (cl.getlength (),1000);
cout << "------------------------\n";
cout << "链表的长度为:" << cl.getlength () << endl;
cout << "打印链表数据:"; cl.printList (); cout << endl;
}
//==========================================
int main ()
{
t5 ();
return 0;
}
最后建议把以上代码复制到自己的编译器上,因为上面的字体看着好费劲(我是从我自己的编译器里写好了之后复制到这里的)
提示:此篇文章为博主原创文章,未经博主许可,不得转载或用于商业用途。