一、单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个节点的构成:(元素+指针) 元素就是存储数据的存储单元,指针就是连接每个节点的地址数据。
定义:每个结点 除了存放数据元素外,还要存储指向下一个节点的指针;
优点:不要求大片连续空间,改变容量方便;
缺点:不可随机存取,要耗费一定空间存放指针
局限性:无法逆向检索
二、单链表的代码
1、单链表的结点类型
typedef int ElemType;
typedef struct LNode{ //定义单链表结点类型
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
2、单链表的基本操作
1、头插法建立单链表
//头插法
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、尾插法建立单链表
//尾插法
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、按序号查找结点的值
//按序号查找
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、按值查找表结点
//按值查找
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、插入结点操作
//插入
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、删除结点
//删除
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、打印链表
//打印
void PrintList(LinkList L){
L = L->next;
while(L!=NULL){
cout<<L->data<<" ";
L=L->next;
}
cout<<endl;
}
3、主程序
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;
}
三、全部代码
#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;
}