以下是数据结构中单向链表的声明、初始化、增加节点、删除节点、插入节点、搜索节点的基本操作:
链表的声明:
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;
}
特别说明:本程序仅挑取关于链表的关键操作进行介绍,对于边界问题(如删除头结点)等特殊情况并没有做出处理。