1. Single linked list
A singly linked list is a chained access data structure that uses a set of storage units with arbitrary addresses to store data elements in a linear list. The data in the linked list is represented by nodes. The composition of each node is: (element + pointer). The element is the storage unit that stores the data, and the pointer is the address data connecting each node.
Definition: In addition to storing data elements, each node also stores a pointer to the next node;
Advantages: Does not require large continuous space, easy to change capacity;
Disadvantages: No random access, it takes a certain amount of space to store pointers
Limitations: Unable to reverse search
2. Code for singly linked list
1. Node type of singly linked list
typedef int ElemType;
typedef struct LNode{ //定义单链表结点类型
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
2. Basic operations of singly linked list
1. Create a singly linked list using head insertion method
//头插法
LinkList CreatList1(LinkList &L){ //逆向建立单链表
LNode *s;
int x;
L = (LinkList)malloc(sizeof(LNode)); //创建头结点
L->next = NULL; //初始值为空链
cin>>x; //输入结点的值
while(x!=9999){ //输入9999表示结束
s = (LinkList)malloc(sizeof(LNode));//创建新节点
//顺序不能改变
s->data = x;
s->next = L->next; //将新结点插入表中,L为头指针
L->next = s;
cin>>x;
}
return L;
}
2. Create a singly linked list using tail insertion method
//尾插法
LinkList CreatList2(LinkList &L){ //正向建立单链表
int x; //设元素类型为整形
L = (LinkList)malloc(sizeof(LNode)); //创建头结点
LNode *s,*r = L; //r为表尾指针
cin>>x; //输入结点的值
while(x!=9999){ //输入9999表示结束
s = (LinkList)malloc(sizeof(LNode));//创建新节点
s->data = x;
r->next = s;
r = s; //r指向新的表尾结点
cin>>x;
}
r->next = NULL; //尾结点指针置为空
return L;
}
3. Find the value of the node according to the serial number
//按序号查找
LNode *GetElem(LinkList L,int i){
int j=1; //计数,初始值为1
LNode *p = L->next; //第一个结点指针赋给P
if(i==0){
return L; //若i等于0,则返回头结点
}
if(i<1){
return NULL; //若i无效,则返回NULL
}
while(p&&j<i){ //从第一个结点开始找,查找第i个结点
p=p->next;
j++;
}
return p; //返回第i个结点的指针
}
4. Find table nodes by value
//按值查找
LNode *LocateElem(LinkList L,ElemType e){
LNode *p = L->next;
while(p!=NULL && p->data==e){ //从第1个结点开始查找data域为e的结点
p=p->next;
}
return p; //找到后返回该结点指针,否则返回NULL
}
5. Insert node operation
//插入
bool ListFroneInsert(LinkList L,int i,ElemType e){
LNode *p = GetElem(L, i-1); //查找插入位置的前驱结点
if(p==NULL){
return false;
}
LNode *s = (LinkList)malloc(sizeof(LNode));
s->data = e; //将e的值赋值给新结点的数据域
s->next = p->next; //插入操作
p->next = s;
return true;
}
6. Delete nodes
//删除
bool ListDelete(LinkList L,int i){
LNode *p = GetElem(L, i-1); //查找删除位置的前驱结点
if(p==NULL){
return false;
}
LNode *q = p->next; //将q指向被删除的结点
p->next = q->next; //将*q结点断开
free(q); //释放结点
q=NULL; //赋值NULL,防止野指针
return true;
}
7. Print the linked list
//打印
void PrintList(LinkList L){
L = L->next;
while(L!=NULL){
cout<<L->data<<" ";
L=L->next;
}
cout<<endl;
}
3. Main program
int main(){
//输入的数据3 4 5 6 7 9999
LinkList L;
LinkList search;
// CreatList1(L); //头插法
CreatList2(L); //尾插法
PrintList(L); //打印链表
//查找第二个元素
search = GetElem(L, 2);
cout<<search->data<<endl;
//在第二个位置插入99
bool res = ListFroneInsert(L,2,99);
if(res){
cout<<"插入成功"<<endl;
PrintList(L);
}else{
cout<<"插入失败"<<endl;
PrintList(L);
}
//删除第二个元素
bool res2 = ListDelete(L,2);
if(res){
cout<<"删除成功"<<endl;
PrintList(L);
}else{
cout<<"删除失败"<<endl;
PrintList(L);
}
return 0;
}
3. All codes
#include <bits/stdc++.h>
using namespace std;
//单链表
typedef int ElemType;
typedef struct LNode{ //定义单链表结点类型
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
//头插法
LinkList CreatList1(LinkList &L){ //逆向建立单链表
LNode *s;
int x;
L = (LinkList)malloc(sizeof(LNode)); //创建头结点
L->next = NULL; //初始值为空链
cin>>x; //输入结点的值
while(x!=9999){ //输入9999表示结束
s = (LinkList)malloc(sizeof(LNode));//创建新节点
//顺序不能改变
s->data = x;
s->next = L->next; //将新结点插入表中,L为头指针
L->next = s;
cin>>x;
}
return L;
}
//尾插法
LinkList CreatList2(LinkList &L){ //正向建立单链表
int x; //设元素类型为整形
L = (LinkList)malloc(sizeof(LNode)); //创建头结点
LNode *s,*r = L; //r为表尾指针
cin>>x; //输入结点的值
while(x!=9999){ //输入9999表示结束
s = (LinkList)malloc(sizeof(LNode));//创建新节点
s->data = x;
r->next = s;
r = s; //r指向新的表尾结点
cin>>x;
}
r->next = NULL; //尾结点指针置为空
return L;
}
//按序号查找
LNode *GetElem(LinkList L,int i){
int j=1; //计数,初始值为1
LNode *p = L->next; //第一个结点指针赋给P
if(i==0){
return L; //若i等于0,则返回头结点
}
if(i<1){
return NULL; //若i无效,则返回NULL
}
while(p&&j<i){ //从第一个结点开始找,查找第i个结点
p=p->next;
j++;
}
return p; //返回第i个结点的指针
}
//按值查找
LNode *LocateElem(LinkList L,ElemType e){
LNode *p = L->next;
while(p!=NULL && p->data==e){ //从第1个结点开始查找data域为e的结点
p=p->next;
}
return p; //找到后返回该结点指针,否则返回NULL
}
//插入
bool ListFroneInsert(LinkList L,int i,ElemType e){
LNode *p = GetElem(L, i-1); //查找插入位置的前驱结点
if(p==NULL){
return false;
}
LNode *s = (LinkList)malloc(sizeof(LNode));
s->data = e; //将e的值赋值给新结点的数据域
s->next = p->next; //插入操作
p->next = s;
return true;
}
//删除
bool ListDelete(LinkList L,int i){
LNode *p = GetElem(L, i-1); //查找删除位置的前驱结点
if(p==NULL){
return false;
}
LNode *q = p->next; //将q指向被删除的结点
p->next = q->next; //将*q结点断开
free(q); //释放结点
q=NULL; //赋值NULL,防止野指针
return true;
}
//打印
void PrintList(LinkList L){
L = L->next;
while(L!=NULL){
cout<<L->data<<" ";
L=L->next;
}
cout<<endl;
}
int main(){
//输入的数据3 4 5 6 7 9999
LinkList L;
LinkList search;
// CreatList1(L); //头插法
CreatList2(L); //尾插法
PrintList(L); //打印链表
//查找第二个元素
search = GetElem(L, 2);
cout<<search->data<<endl;
//在第二个位置插入99
bool res = ListFroneInsert(L,2,99);
if(res){
cout<<"插入成功"<<endl;
PrintList(L);
}else{
cout<<"插入失败"<<endl;
PrintList(L);
}
//删除第二个元素
bool res2 = ListDelete(L,2);
if(res){
cout<<"删除成功"<<endl;
PrintList(L);
}else{
cout<<"删除失败"<<endl;
PrintList(L);
}
return 0;
}