单链表,用指针来实现的线性表
为了方便操作,我们定义一个头指针来操作链表
结构体为Node 一个整型data,一个Node指针next指向下一个节点
封装类为LinkList 链表的各个操作具体看类的函数即可。
/*
* 单链表的实现
*为了看起来简单点,这里用int类型作为链表的数据类型
*/
#include<iostream>
using namespace std;
//定义一个结构体。data存贮数据,next指针指向下一个数据
struct Node
{
int data;
Node * next;
} ;
class LinkList
{
public:
LinkList() //无参的构造函数,构造一个空的链表
{
first = new Node;
first->next = NULL;
}
//有参构造函数,我把尾插法和头插法建立链表都放里面了
LinkList(int a[],int n)
{
/*
*
//头插法建立单链表 ---我不喜欢用这个,注释掉
first = new Node;//初始化指针
first->next = NULL;
for(int i = 0;i < n;i++)
{
Node *s = new Node;
s->data = a[i];
s->next = first->next; //节点s的指针域指向头指针的下一个数据体
first->next = s; //头指针的指针域指向s。
//这两行代码实现了将一个节点s插入到头指针的下一个节点
}
*/
/*
*尾插法建立单链表
*/
first = new Node;//生成头节点
Node *r = first;//初始化尾指针
for(int i = 0;i < n;i++)
{
//创建一个节点
Node *s = new Node;
s->data = a[i];
r->next = s; //尾指针的下一个节点指向是s
r = s; //尾指针r移到s节点
}
r->next = NULL;//单链表创建完毕,将终端节点指针域置空
}
//析构函数,释放资源
~LinkList()
{
while(first != NULL)
{
Node *q = first;//暂存被释放的节点
first = first->next;//first节点往后移
delete q;
}
}
int Getlength() //求单表的长度
{
Node *p = first->next;//p指向链表第一个非空节点(不是头结点),操作链表
int count = 0;
while(p != NULL)
{
p = p->next;
count++;
}
return count;
}
int Get(int i ) //按位查找,在单链表中查找第i个元素
{
Node *p = first->next;
int count = 1;
while(p != NULL && count < i)
{
p = p->next;
count++;
}
if(p == NULL)
throw "位置不正确";
else
return p->data;
}
int Locate(int x) //按值查找,查找单链表中值为x的元素序号
{
Node *p = first->next;
int count = 1;
//循环遍历单链表,如果找到相等数据,返回count
while(p != NULL)
{
if(p->data == x)
return count;
p = p->next;
count++;
}
//退出循环代表查找失败,链表中没有这个数据
return 0;
}
void Insert(int i ,int x) //插入操作,在单链表中第i个位置插入值为x的元素
{
Node *p = first;//工作指针应该指向头结点
int count = 0;
//循环,工作节点p找到第i个节点的位置
while(p != NULL && count < i-1)
{
p = p->next;
count++;
}
if(p == NULL)
throw "位置不正确";
else
{
//建立新节点
Node *s = new Node;
s->data = x;
//将节点s插入到节点p之后
s->next = p->next;
p->next = s;
}
}
int Delete(int i) //删除操作,删除表中的第i个元素
{
Node *p = first;
int count = 0;
//工作指针找到i的前一个节点位置
while(p != NULL && count < i-1)
{
p = p->next;
count++;
}
if(p == NULL || p->next == NULL) //如果节点p不存在或者p的后继节点不存在
throw "位置不正确";
else
{
Node *q = p->next; //暂存被删除节点
int x = q->data;
p->next = q->next;//将第i个节点从链表中摘除
delete q;
return x;
}
}
void PrintList() //遍历操作,按序号输入出各个元素
{
Node *p = first->next;
while(p != NULL)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
}
private:
Node *first; //头指针
} ;
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,0};
int n = 10;
LinkList ll(a,n);
cout<<"第5个数据是:"<<ll.Get(5)<<endl;
cout<<"链表的长度时:"<<ll.Getlength()<<endl;
cout<<"值为6的数据所在的位置是:"<<ll.Locate(6)<<endl;
cout<<"遍历插入前的链表:";
ll.PrintList();
cout<<"往第7个位置插入数据12";
ll.Insert(7,12);
cout<<"遍历插入后的链表:";
ll.PrintList();
cout<<"删除第三个数据后的链表:";
ll.Delete(3);
ll.PrintList();
return 0;
测试结果:
![](https://i-blog.csdnimg.cn/blog_migrate/6d1d931e2636c09d727c36cebbd39907.png)
还可以通过控制台数据数据,然后将用户手动输入的数据存放在链表中,这个实现起来应该不难,稍微修改一下代码就可以啦