链表为线性表的存储结构之一,相比于数组(顺序表),链表在插入、删除操作简便。
基本知识
头结点前放置first指针,始终指向第一个节点前的位置。
初始化链表
将first指针后结点置空(此状态也是空链表的条件,可以用于判空表)
注:指针的数据类型为无符号长整型,空指针的数值为0
构建链表
操作分两种:头插法(插入到表头)、尾插法(插入到表尾)【需要用到临时指针s,先赋值,后对s挂链】
头插法
int i;
for(i=0;i<n;i++){
Node *s=NULL;
s=new Node;
s->data=a[i]; //数组数据转入临时指针s
s->next=first->next;//对s挂链
first->next=s; //头部挂链,实现头插
}
尾插法
first=new Node;
Node *r=first,*s=NULL; //建立尾指针r,辅助指针s
int i;
for(i=0;i<n;i++){
s=new Node ;
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL; //尾指针置空
}
添加、删除操作
添加、删除操作的工作指针p都指向要修改的元素前一个位置。
添加操作
需要使用临时指针s,工作指针p。先对s构建,后赋值s数据域,之后挂链。
void LinkList::add(int i,int x){ //添加元素到i位置
Node *p=NULL,*s=NULL;
p=first;
int cnt=0;
//定位到第i-1个位置,之后进行插入操作
while(p && cnt<i-1){
cnt++;
p=p->next;
}
if(!p) throw"找不到指定位置!";
else
{
s=new Node;
s->data=x;
s->next=p->next;
p->next=s;
}
}
删除操作
先暂存,后摘链(被删除元素的下一节点为工作指针的下一位置,即跳过被删除节点)【删除操作需要使用工作指针p,】
int LinkList::del(int i){ //删除第i个元素
Node *p=first;
Node *q=NULL;
int tmp;
int cnt=0;
//删除之前指针先指向要删除元素的前一个位置
while(p && cnt<i-1){
p=p->next;
cnt++;
}
if( !p&& (!p->next) ) throw"找不到指定位置!";
else{
q=p->next;tmp=q->data; //q指向被删结点以暂存被删结点信息
p->next=q->next; //p为要删除元素的前一个位置
delete q;
return tmp; //得到被删点的数据
}
}
析构函数
使用循环,从first开始,删除所有节点(delete操作)
遍历链表
使用工作指针,从第一个指针开始,循环遍历全部节点
注:不可使用p++ 只能用 p=p->next
Node *p=first->next;
int cnt=0;
//计算长度cnt初始值为1,其他情况下初值一般为0
cout<<"当前表内元素为:";
while(p){
cout<<p->data<<" ";
cnt++;
p=p->next;
}
定位、查找操作
需要使用工作指针、计数变量。第一步应判空,之后用工作指针循环遍历链表。
代码实现
结构体定义
struct Node{
int data;
Node *next;
};
类定义
class LinkList{
public:
LinkList(); //无参构造函数
void defaultlink(); //链表初始化操作
LinkList(int a[],int n);//有参构造:建立n个数据的表
~LinkList(); //析构函数
int length(); //获取链表长度
int get(int i); //得到第i个元素
int located(int x); //定位指定元素的位置
void add(int i,int x); //添加元素
int del(int i); //删除第i个元素
int empty(); //判空
void print(); //输出表
private:
Node *first;
//头指针指向第一个元素前面的位置(相当于第一个元素的前驱结点)
};
完整代码
#include<iostream>
using namespace std;
struct Node{
int data;
Node *next;
};
class LinkList{
public:
LinkList(); //无参构造
void defaultlink(); //初始化
LinkList(int a[],int n);//建立n个数据的表
~LinkList(); //析构
int length(); //获取长度
int get(int i); //得到第i个元素
int located(int x); //定位指定元素的位置
void add(int i,int x); //添加元素
int del(int i); //删除第i个元素
int empty(); //判空
void print(); //输出表
private:
Node *first; //设置first指针【注意数据类型】
};
void LinkList::defaultlink(){ //初始化first语句
first=new Node;
first->next=NULL;
}
LinkList::LinkList() { //初始化:构造生成只有头结点的表
defaultlink();
}
LinkList::LinkList(int a[],int n){
defaultlink();
//头插
// int i;
// for(i=0;i<n;i++){
// Node *s=NULL;
// s=new Node;
// s->data=a[i]; //数组数据转入链表
// s->next=first->next;
// first->next=s; //头部挂链,实现头插
// }
//尾插
first=new Node;
Node *r=first,*s=NULL;
int i;
for(i=0;i<n;i++){
s=new Node ;
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL; //尾指针置空
}
LinkList::~LinkList(){ //删除所有节点
Node *p=first;
while(p){
delete p;
p=p->next;
}
delete p;
delete first;
}
int LinkList::length(){
int cnt=1; //cnt计数:从1开始
Node *p=NULL;
p=first->next;
while(p->next){
cnt++;
p=p->next;
}
return cnt;
}
int LinkList::get(int i){ //按位置查找元素
Node *p=first->next;
int f=0;
while(p && f<i){
p=p->next;
f++;
}
if(!p) throw"无法查找!";
else return p->data;
}
int LinkList::located(int x){ //按值查找
Node *p=first->next;
if(!p) throw"无法查找!";
int cnt=0;
int flag=0;
while(p){
if(p->data==x) flag=cnt;
cnt++;
p=p->next;
}
return flag;
}
void LinkList::add(int i,int x){ //添加元素
Node *p=NULL,*s=NULL;
p=first;
int cnt=0;
//定位到第i-1个位置,之后进行插入操作
while(p && cnt<i-1){
cnt++;
p=p->next;
}
if(!p) throw"找不到指定位置!";
else
{
s=new Node;
s->data=x;
s->next=p->next;
p->next=s;
}
}
int LinkList::del(int i){ //删除第i个元素
Node *p=first;
Node *q=NULL;
int tmp;
int cnt=0;
//删除之前指针先指向要删除元素的前一个位置
while(p && cnt<i-1){
p=p->next;
cnt++;
}
if( !p&& (!p->next) ) throw"找不到指定位置!";
else{
q=p->next;tmp=q->data; //q指向被删结点以暂存被删结点信息
p->next=q->next; //p为要删除元素的前一个位置
delete q;
return tmp; //得到被删点的数据
}
}
int LinkList::empty(){
if(first->next=NULL) throw"the LinkList is empty!";
return 0;
}
void LinkList::print(){
Node *p=first->next;
cout<<"当前表内元素为:";
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main(){
int num[5]={0,1,2,3,4};
int i,x;
LinkList L(num,5);
L.add(4,20) ;
L.print();
cout<<"length="<<L.length();
//可以调用成员函数进行添加元素、删除元素等其他操作
return 0;
}