链表基础
一、单链表
1.数据定义
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
2.链表初始化
//初始化
void init(LinkList &l){
l=new LNode;
l->next=null;
}
3.头插法
//头插法插入元素
void insertHead(LinkList l,LNode e){
e.next=l->next;
l->next=e;
}
4.尾插法
/
/尾插法插入元素
void insertRear(LinkList l,LNode e){
//找到最后一个结点
while(l->next)l=l->next;
l->next=e;
e.next=null;
}
5.插入指定位置
//指定位置初始化
bool insert(LinkList l,int i,LNode e){
//插入位置不合法
if(i>(length(l)+1)){
return false;
}
//插入到第i个,找到其前驱i-1就可以了
int j=0;
while(l && j!=i-1){
j++;
l=l->next;
}
//开始插入
e.next=l->next;
l->next=e;
return true;
}
6.定位元素位置
int locate(LinkList l,LNode e){
int i=0;
bool flag=flase;
while(l){
l=l->next;
i++;
//找到之后更改flag
if(l->data==e.data){
flag=true;
break;
}
}
//找到返回位置
if(flag)return true;
//查找失败
return 0;
}
7.获取指定位置的元素
//获取指定位置的元素
LinkList charAt(LinkList l,int i){
//位置不合法
if(i>length){
return NULL;
}
int j=0;
while(l && ++j!=i)l=l->next;
return l;
}
8.寻找指定元素前驱
//返回当前元素的前驱
LinkList preElement(LinkList l,LNode e){
//判断后继是否是要找的元素
while(l && l->next.data!=e.data)l=l->next;
return l;
}
9.寻找指定元素后继
//返回当前元素的后继
LinkList nextElement(LinkList l,LNode e){
//从第一个结点开始
l=l->next;
//找到指定元素返回后继即可
while(l && l->data!=e.data)l=l->next;
return l->next;
}
10.删除指定位置元素
//删除指定位置元素
bool remove(LinkList l,int i){
//位置不合法
if(i>length(l))return false;
int j=0;
//找到其前驱
while(l && ++j!=i-1)l=l->next;
//断链了----感觉有点多余
if(!l)return false;
//删除
LinkList p;
p=l->next;
l->next=p->next;
delete p;
return true;
}
11.长度
//获取链表长度 默认链表存在
int length(LinkList l){
int len=0;
l=l->next;
while(l){
len++;
l=l->next;
}
return l;
}
12.判空
//判断列表是否为空
bool IsEmpty(LinkList l){
if(l->next)return false;
return true;
}
13.清空
//总感觉这里理解有错误-
//清空------头结点后继置空即可---后面的链接还于人海
void clear(LinkList l){
l->next=null;
}
14.销毁
//销毁的话就是一个结点一个结点的释放内存
void destory(LinkList l){
LinkList p,q;
//将l后的链给q然后一点点销毁 l后继置空
q=l->next; l=null;
while(q){
p=q;
q=q->next;
delete p;
}
}
15.销毁
//链表的遍历
void display(LinkList l){
if(length(l)==0)return;
cout<<"链表数据如下:"<<endl;
while(l->next){
l=l->next;
cout<<l->data<<" ";
}
cout<<endl;
}
二、双链表
1.数据定义
typedef struct LNode{
int data;
struct LNode *next,*pre;
}LNode,*LinkList;
2.初始化
//初始化
void init(LinkList &l){
l=new LNode;
//头结点前驱和后继指向自身
l->next=l->pre=l;
}
3.头插法
//头插法
void insertHead(LinkList l,LNode e){
LinkList p;
//第一个结点
p=l->next;
//新节点的前驱是头结点,后继是原首结点
e.next=p;
e.pre=l;
//原首结点前驱变为新首结点
p->pre=e;
//头节点的后继变为新首结点
l->next=e;
}
4.尾插法
//尾插法
void insertRear(LinkList l,LNode e){
LinkList p;
//最后一个结点
p=l->pre;
//新尾结点的前驱为原尾结点,后继是头结点
e.pre=p;
e.next=l;
//原尾结点的后继是新尾结点
p->next=e;
//头结点的前驱变为新尾结点
l->pre=e;
}
5.正向遍历删除
//正向遍历删除
bool remove(LinkList l,LNode e){
bool flag=false;
LinkList p;
//遍历一圈会回到原头结点
while(l->next!=l){
if(l->next->data==e.data){
//当前l结点为指定删除结点的前驱
p=l->next;
//前驱结点的新后继为要删除结点的后继
//后继结点的新前驱为要删除结点的前驱
p->next->pre=l;
l->next=p->next;
flag=true;
break;
}
}
return flag;
}
6.正向遍历
//遍历
void display(LinkList l){
while(l->next!=l){
l=l->next;
cout<<l->next<<" ";
}
cout<<endl;
}