【数据结构】浅谈单链表的C++实现

链表为线性表的存储结构之一,相比于数组(顺序表),链表在插入、删除操作简便。

基本知识

头结点前放置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;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值