单链表的c++和c语言的写法(一)
- 使用c++语法写一个单链表。
首先定义一个类,取名为LinkNode。
#include<iostream>
using namespace std;
typedef struct SListNode//结构体
{
int data;
SListNode* next;
}SN,SListNode;
class LinkNode
{
public:
void SListNodeInit(); //初始化函数
void SListNodePrint(); //输出函数
int SListNodeGetLength(); //长度返回函数
SN* SListNodeBuyNode(int x); //新建节点函数
void SListNodeInsert(int pos, int x); //插入函数
void SListNodeDelete(int pos, int* value); //删除函数
void SListNodeClear(); //清除函数
void SListNodedestory(); //销毁函数
private:
int length; //链表的长度
SListNode* phead; //头指针
};
到这里为止,我们已经建好了类,也完成了函数申明。现在要在类外进行函数定义。
1.初始化函数
思路:这里的初始化具体指的是对头指针phead以及length的初始化。让length初始化为0不再赘述,而这里的phead是首元节点,不储存数据data,只储存下一节点的地址,所以一般不把它当作第一个节点,而是零号节点。
oid LinkNode::SListNodeInit()
{
phead = new SN; //分配动态内存
if (phead == NULL)
{
cout<<"分配失败"<<endl;
exit(-1);
}
phead->next = NULL;
length = 0;
}
2.输出函数
思路:定义一个节点cur,让它指向第一个节点(不是零号捏),再遍历链表。
void LinkNode::SListNodePrint()
{
cout << "单链表长度为:" << length << endl;
if (length != 0)
{
SN* cur = phead->next;
int i=0;
while (i<length)
{
cout<<cur->data<<"->";
cur = cur->next;
i++;
}
cout << "NULL" << endl;
}
}
3.新建节点函数
思路:可能这个函数看起来有点没必要,但很多复杂功能的实现需要这一步,所以独立为一个函数可以使思路更清晰。
SN* LinkNode::SListNodeBuyNode(int x)
{
SN* newNode = new SN;
if (newNode == NULL)
{
cout << "分配失败" << endl;
exit(-1);
}
newNode->data = x;
newNode->next = NULL;
return newNode;
}
4.插入函数
思路,由于单链表的缺陷,它无法找到上一个节点的地址,只能找到下一个结点的地址。因此,当我们选择了插入位置为pos时,应该先通过循环找到pos之前的那一个节点prev。然后在prev的后面插入新节点newNode。
与此同时,再插入newNode时,我们要注意节点之间连接断开的顺序!!这一点新手很容易产生错误。结尾的时候记得把length加1喔。
void LinkNode::SListNodeInsert(int pos,int x)
{
SN* cur = phead;//用于遍历的节点
SN* newNode = SListNodeBuyNode(x);//待插入的节点
for (int i = 0; i < pos - 1; i++)//找到待插入位置的前一个
{
cur = cur->next;
}
newNode->next = cur->next;//插入
cur->next = newNode;
newNode->data = x;
length++;
}
5.删除元素函数
思路:删除元素的思路与插入函数基本相同,还是找前一个。
值得注意的是,在参数中我们定义了一个指针变量value,这是为了保存我们删除的节点所保存的值data,防止之后会用到。
void LinkNode::SListNodeDelete(int pos,int*value)
{
SN* cur = phead;
for (int i = 0; i < pos - 1; i++);
{
cur = cur->next;
}
SN* newNode = cur->next;
*value = newNode->data;
cur->next = newNode->next;
delete newNode;
length--;
}
6.清除函数与销毁函数
void LinkNode::SListNodeClear()
{
int len = length;
int temp;
if (len > 0)
{
for (int i = 0; i < len; i++)
delete(1, &temp);
}
}
void LinkNode::SListNodedestory()
{
if (length > 0)
SListNodeClear();
delete phead;
}
6.长度返回函数
int LinkNode::SListNodeGetLength()
{
return length;
}
至此,单链表的基本功能已经完成了,我们得在主函数中调用这些函数。
在这里我习惯写一个测试函数。
void SListNodeTest()
{
LinkNode s1;
s1.SListNodeInit();
for (int i = 0;i<20;i++)
{
s1.SListNodeInsert(s1.SListNodeGetLength() + 1, i + 1);
}
s1.SListNodePrint();
int v;
for (int j = 0;j< 10; j++)
{
s1.SListNodeDelete(j+2,&v);
//cout << v << endl;
}
s1.SListNodePrint();
s1.SListNodeClear();
s1.SListNodedestory();
}
void main()
{
SListNodeTest();
}
c语言部分将在下一篇中展示。