单链表的各种操作的回顾
单链表的定义:
定义
注意!!!:Lnode为普通的类型,LinkList是指向Lnode的指针,即Lnode x=LinkList x;
一般将数据封装成ElemType,然后再定义Lnode
#include <iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef int Status;//返回值类型
typedef char ElemType;//数据类型
using namespace std;
typedef struct Lnode{
ElemType data;
Lnode* next;
}Lnode,*LinkList;
//带头结点链表初始化
//1.将链表指向头结点,并且头结点的下一个指向为空
Status initList(LinkList &L){
//Lnode L=new Lnode;//c++语法用delete销毁,c的语法为;用free销毁
L=(LinkList)malloc(sizeof(Lnode));
L->next=nullptr;
return OK;
}
//判断链表是否为空
int isEmpty(LinkList L){
if(L->next!=nullptr) return 0;
else return 1;
}
//销毁单链表
void destoryLink(LinkList &L){
LinkList p;
//注意点:L->next=null时是最后一个节点,不是循环结束的条件
//循环结束的条件为L=null;
//while(L!=nullptr){
// p=L;
// L=L->next;
// free(p);
//}
//或者
p=L;
//这里的循环结束的条件为L=null或者p=null
while(p){
L=L->next;
free(p);
p=L;
}
}
//清空链表(头结点保存,从首元结点开始删除)
Status clearLink(LinkList &L){
LinkList pre,cur;
// if(L->next!=nullptr){
// pre=L->next;
// cur=pre->next;
// while(cur){
// free(pre);
// pre=cur;
// cur=cur->next;
// }
//}
pre=L->next;
while(pre){
cur=pre->next;
free(pre);
pre=cur;
}
L->next=nullptr;//头结点的指针域设置为空
return OK;
}
//求单链表的表长
void getLinkLength(LinkList L,int &len){
LinkList p;
p=L->next;
len=0;//设置初值
while(p!=nullptr){
len++;
p=p->next;
}
}
//取第i个元素值
Status getElemI(LinkList &L,int i,ElemType &e){
int index=1;
Lnode* p;
p=L->next;//首元结点,所以index从1开始
//如果一开始j>i说明要找的位置i比1小,是非法的
while(p&&index<i){
p=p->next;
index++;
}
if(!p||index>i) return ERROR;
e=p->data;
return ERROR;
}
//按值查找,返回地址
Lnode* LocteElemE(LinkList L,ElemType e){
Lnode* p;
p=L->next;
while(p&&p->data!=e){
p=p->next;
}
return p;
}
//按值查找,返回在第几个
int LocateElemE2(LinkList L,ElemType e){
int i=1;
Lnode* p;
p=L->next;
while(p&&p->data!=e){
p=p->next;
i++;
}
if(p==nullptr) return 0;
else return i;
}
Status insertLink(LinkList &L,int i,ElemType e){
Lnode* p=L;
int index=0;
while(p&&index<(i-1)){
p=p->next;
index++;
}
if(!p||index>i-1){//!p说明大于表长+1;index>i-1说明小于1
return ERROR;
}else{
Lnode* s=(LinkList)malloc(sizeof(Lnode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
}
Status deleteLink(LinkList &L,int i,ElemType &e){
int index=0;
Lnode* p;
p=L;
//或者需要用中间变量存储p->next
//Lnode* q;
while(p&&index<(i-1)){//index=i-1或者p为空的时候跳出循环
p=p->next;
index++;
}
if(p||index>(i-1)){
return ERROR;
}else{
//q=p->next;
//p->next=q->next;
//e=q->data;
e=p->next->data;
p->next=p->next->next;
return OK;
}
}
//头插法
void headInsert(LinkList &L,ElemType e){
Lnode* p=(LinkList)malloc(sizeof(Lnode));
//或者用户输入这个元素的值
//cin>>e;
//scanf(e);
p->data=e;
p->next=L->next;//原来的接在新节点的后面
L->next=p;//新节点接在头结点的后面
}
//尾插法
void tailInsert(LinkList &L,int n){
Lnode* tail;
tail=L;//指向头结点
while(n!=0){
Lnode* p=new Lnode;//记得每次都要开辟一块空间,否则输入会产生错误
cin>>p->data;
p->next=nullptr;//新指针的下一个指针域设置为空
tail->next=p;//把尾指针的下一个指向当前的新指针
tail=p;//移动尾指针的位置
n--;//减少
}
}
//遍历链表
void selectLink(LinkList L){
Lnode* p;
p=L->next;
if(p==nullptr){
printf("这个链表是空的!");
}
while(p!=nullptr){
printf("p->data: %c\n",p->data);
p=p->next;
}
}
int main()
{
//测试:
LinkList L;
initList(L);
//ElemType elem[5]={'a','b','c','d','e'};
//for(int i=4;i>=0;i--){
// headInsert(L,elem[i]);
//}
tailInsert(L,5);
selectLink(L);
//insertLink(L,6,'f');
//printf("插入后:\n");
ElemType result;
getElemI(L,5,result);
printf("取出第5个元素的值为%c\n",result);
Lnode* p=LocteElemE(L,'a');
printf("按值查找返回地址:%c\n",p->data);
int i=LocateElemE2(L,'a');
printf("按值查找返回第几个: %d\n",i);
selectLink(L);
int len;
getLinkLength(L,len);
printf("链表长度:%d\n",len);
return 0;
}