数据结构——单向链表(声明、初始化、增加、删除、插入、搜索、修改)

以下是数据结构中单向链表的声明、初始化、增加节点、删除节点、插入节点、搜索节点的基本操作:

链表的声明:

typedef struct LNode{
	LNode *next;
	int data;
}LNode,*LinkList; 

此处的结构体名为LNode,别名LNode、LinkList。

链表的初始化

void initial(LNode *&List){
	List = new LNode;
	List->data = 0;
	List->next = NULL;
	cout<<"单向链表初始化完毕!初始节点data为0"<<endl; 
}
int main(){
	LNode *List;
	initial(List);
	return 0;
}

声明一个节点,作为首节点,下一个节点设置为空。

新增节点

void addNode(LinkList &List,int data){//增加一个节点 
	LNode *p = List;
	while(p->next!=NULL){
		p = p->next;
	}
	LNode *node = new LNode;
	node->next = NULL;
	node->data = data;
	p->next = node;
}

void add(LinkList &List){//LinkList &List等价于LNode *&List
	int c;
	while(1){
		cout<<"请输入新增节点的data(输入-1停止新增):"; 
		cin>>c;
		if(c==-1){
			break;
		}
		addNode(List,c);
	}
	cout<<"节点新增完成!";
	showList(List); 
}

将链表地址传入函数中,再进行操作。
值得注意的是:LinkList &List等价于LNode *&List

插入节点

void insertNode(LinkList &List,int index){
	int i = 1;
	//如果data插入到第index个元素前,i设为1。 
	//如果插入到第index个元素后,i设为0。 
	LNode *p = List;
	while(p != NULL && i < index){ 
		i++;
		p = p->next;
	}
	if(i<index || !p){
		cout<<"插入位置超出链表长度!";
	}else{
		LNode *node = new LNode;
		node->next = p->next;
		int data;
		cout<<"请输入新节点的data:";
		cin>>data;
		node->data = data;
		p->next = node;
	}
}

void insert(LinkList &List){
	cout<<"请输入插入数据的位置(从1开始算):";
	int index;
	cin>>index;
	insertNode(List,index);
	cout<<"节点插入完成!";
	showList(List); 
}

如果data插入到第index个元素前,i设为1。
如果data插入到第index个元素后,i设为0。

删除节点

Boolean delNode(LNode *&List,int index){
	int i = 0; 
	LNode *p = List;
	while(p->next != NULL && i+1 < index){ 
		i++;
//		cout<<p->data<<" ";
		p = p->next;
	}
	if(i+1<index||!p){
		return ERROR; 
	}else{
		LNode *t = new LNode;
		t = p->next;
		
		p->next = t->next;//p指向下一个地址(被删除地址)的下一个地址 
	//	t = t->next;
	//	p->next = t;
	//	t = NULL
	//如果是把t->next和p->next分开写一定要记得先把当前t对应的地址去除
	//否则delete t 就是把该地址清空
	//也就是把链表对应的位置一并清除了,导致野指针程序出错 
		delete t; 
		return OK;
	}  
}

void del(LinkList &List){
	int index;
	cout<<"请输入删除节点的下标(从1开始算起):";
	cin>>index;
	if(delNode(List,index)){
		cout<<"第"<<index<<"个节点删除完成!";
		showList(List);
	}else{
		cout<<"节点删除失败!"<<endl;
	}
}

p->next = t->next;//p指向下一个地址(被删除地址)的下一个地址
也可以写成:
t = t->next;
p->next = t;
t = NULL;
值得注意的是:如果是把t->next和p->next分开写一定要记得先把当前t对应的地址去除,否则delete t 就是把该地址清空也就是把链表对应的位置一并清除了,导致野指针程序出错。

搜索(修改)节点

Boolean searchNode(LinkList &List, int data){
	LinkList p = List;
	int index = 0;
	Boolean flag = ERROR;
	while(p!=NULL){
		if(p->data == data){
			cout<<"查找成功!第"<<index<<"个节点数据为"<<data<<endl;
			flag = OK; 
			//此处不设置跳出是为了查询相同元素的全部下标位置
			//如果只需要查询第一次出现的位置,在此处设置跳出循环即可 
		}
		p = p->next;
		index++;
	}
	return flag;
}

void search(LinkList &List){
	int data;
	cout<<"请输入要查找的data:";
	cin>>data;
	if(!searchNode(List,data)){//取非 
		cout<<"No this data!"<<endl; 
	}
}

如果是修改操作,只需要在查询成功那里进行修改即可。

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

源代码:

/*
		广西师范大学 计算机科学与工程学院 
		GuangXi Normal University College of Computer Science and Engineering  
		Student STZ 
*/ 
#include<iostream>
#include<stdio.h>
using namespace std;
//此处定义宏,增加程序可读性 
#define Boolean int
#define OK 1
#define ERROR 0

typedef struct LNode{
	LNode *next;
	int data;
}LNode,*LinkList; 


void showList(LinkList &List){//等价于LNode *&List
	LNode *p = List;
	LNode *s = List;
	int index = 0;
	cout<<"当前链表信息:"<<endl;//此处输出下标所用,没有实际意义 
	while(s!=NULL){
		cout<<index++<<" ";
//		cout<<s->data<<" ";
		s = s->next;
	}
	cout<<"<-下标"<<endl;
	while(p!=NULL){
		cout<<p->data<<" ";
		p = p->next;
	}
	cout<<"<-节点值"<<endl;
}

void initial(LNode *&List){
	List = new LNode;
	List->data = 0;
	List->next = NULL;
	cout<<"无头结点单向链表初始化完毕!初始节点data为0"<<endl; 
}

void addNode(LinkList &List,int data){//增加一个节点 
	LNode *p = List;
	while(p->next!=NULL){
		p = p->next;
	}
	LNode *node = new LNode;
	node->next = NULL;
	node->data = data;
	p->next = node;
}

void add(LinkList &List){
	int c;
	while(1){
		cout<<"请输入新增节点的data(输入-1停止新增):"; 
		cin>>c;
		if(c==-1){
			break;
		}
		addNode(List,c);
	}
	cout<<"节点新增完成!";
	showList(List); 
}



void insertNode(LinkList &List,int index){
	int i = 1;
	//如果data插入到第index个元素前,i设为1。 
	//如果插入到第index个后,i设为0。 
	LNode *p = List;
	while(p != NULL && i < index){ 
		i++;
		p = p->next;
	}
	if(i<index || !p){
		cout<<"插入位置超出链表长度!";
	}else{
		LNode *node = new LNode;
		node->next = p->next;
		int data;
		cout<<"请输入新节点的data:";
		cin>>data;
		node->data = data;
		p->next = node;
	}
}

void insert(LinkList &List){
	cout<<"请输入插入数据的位置(从1开始算):";
	int index;
	cin>>index;
	insertNode(List,index);
	cout<<"节点插入完成!";
	showList(List); 
}

Boolean delNode(LNode *&List,int index){
	int i = 0; 
	LNode *p = List;
	while(p->next != NULL && i+1 < index){ 
		i++;
//		cout<<p->data<<" ";
		p = p->next;
	}
	if(i+1<index||!p){
		return ERROR; 
	}else{
		LNode *t = new LNode;
		t = p->next;
		
		p->next = t->next;//p指向下一个地址(被删除地址)的下一个地址 
	//	t = t->next;
	//	p->next = t;
	//	t = NULL
	//如果是把t->next和p->next分开写一定要记得先把当前t对应的地址去除
	//否则delete t 就是把该地址清空
	//也就是把链表对应的位置一并清除了,导致野指针程序出错 
		delete t; 
		return OK;
	}  
}

void del(LinkList &List){
	int index;
	cout<<"请输入删除节点的下标(从1开始算起):";
	cin>>index;
	if(delNode(List,index)){
		cout<<"第"<<index<<"个节点删除完成!";
		showList(List);
	}else{
		cout<<"节点删除失败!"<<endl;
	}
}

Boolean searchNode(LinkList &List, int data){
	LinkList p = List;
	int index = 0;
	Boolean flag = ERROR;
	while(p!=NULL){
		if(p->data == data){
			cout<<"查找成功!第"<<index<<"个节点数据为"<<data<<endl;
			flag = OK; 
			//此处不设置跳出是为了查询相同元素的全部下标位置
			//如果只需要查询第一次出现的位置,在此处设置跳出循环即可 
		}
		p = p->next;
		index++;
	}
	return flag;
}

void search(LinkList &List){
	int data;
	cout<<"请输入要查找的data:";
	cin>>data;
	if(!searchNode(List,data)){//取非 
		cout<<"No this data!"<<endl; 
	}
}

void menu(LinkList &List){
	int c = 0;
	while(1){
		cout<<"请选择操作:"<<endl;
		cout<<"1:新增节点"<<endl;
		cout<<"2:插入节点"<<endl;
		cout<<"3:删除节点"<<endl;
		cout<<"4:展示节点"<<endl;
		cout<<"5:搜索节点"<<endl;
		cout<<"6:退出系统"<<endl;
		cin>>c;
		switch(c){
			case 1:add(List);break;
			case 2:insert(List);break;
			case 3:del(List);break;
			case 4:showList(List);break;
			case 5:search(List);break; 
			case 6:return;
			default:;
		} 
	}
}

int main(){
	LNode *List;
	initial(List);
	menu(List); 
	return 0;
}

特别说明:本程序仅挑取关于链表的关键操作进行介绍,对于边界问题(如删除头结点)等特殊情况并没有做出处理。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芣苢的成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值