双向链表
- 定义
typedef struct node
{
int num;
struct node *pre; //前指针
struct node *next;
}stud;
- 双向链表的创建算法
没什么好说的。。。多个指针而已
stud *create(int n)
{
stud *head,*p1,*p2;
for(int i=0;i<n;i++)
{
p1=(stud *)malloc(sizeof(stud));
p1->num=i;
if(i==0)
{
head=p1;
p1->pre=NULL; //!!!
}
else
{
p2->next=p1;
p1->pre=p2; //!!!!!
}
p2=p1; //!!
}
p1->next=NULL;
return head;
}
- 双向链表的查找算法
这里分情况
(1)输入头结点
(2)输入非头结点,链表无序
(3)输入非头结点,链表有序
可以根据不同的情况选择更加适合或者说更简单的算法。
(1)
stud *find_head(stud *head,int i)
{ stud *p1=NULL;
if(head)
{
p1=head;
while(p1!=NULL)
{
if(i==p1->num)
{
break;
}
else
{
p1=p1->next;
}
}
}
return p1;//之前单链表那就想是不是要考虑找不到情况,但其实返回结果是NULL就是没找到。
}
(2)
stud *find_no_sort(stud *p,int i)//不是头结点,我就不考虑空的情况,而且至少两个
{
stud *p1;
p1=p;
while(p1!=NULL)
{
if(i==p1->num)
break;
else
p1=p1->next;//!!!!!!先往后找
}
if(p1==NULL)
{
p1=p;//!
while(p1!=NULL)
{
if(i==p1->num)
break;
else
p1=p1->pre;//!!!!!!再往前找
}
}
return p1;
}
(3)假设从小到大排序,比较与输入结点值大小,小就向前搜索,大就向后,这里就不写了
- 双向链表的删除算法
跟查找一样,也有三种情况
(1)这里我写了个可以删除重复元素的。
bool del_head(stud *head,int i)
{
bool consq=false;
if(head)
{
stud *p1,*p2=NULL;
p1=head;
while(p1!=NULL)
{
p2=p1->pre;
if(i==p1->num)
{
if(p1==head)//!!!!
{
head=p1->next;
p1->next->pre=NULL;//!!!!
}
else
{
p2->next=p1->next;
p1->next->pre=p2;
}
consq=true;
free(p1);
p1=p2->next;//找到一个继续找
}
else
p1=p1->next;
}
}
return consq;
}
(2)这个也是可以删除重复的
bool del_no_sort(stud *p,int i)
{
bool consq=false;
stud *p1,*p2=NULL;
p1=p;
while(p1!=NULL)
{
p2=p1->pre;
if(i==p1->num)
{
if(p1->pre==NULL)//头结点的情况也考虑了
{
p1->next->pre=NULL;
}
else
{
if(p1->next==NULL)//尾结点
{
p2->next=NULL;
}
else
{
p1->next->pre=p2;//假如这里是尾结点这里会出错,所以前面尾结判断不能省
p2->next=p1->next;
}
}
consq=true;
free(p1);
p1=p2->next;//找到一个继续找
}
else
p1=p1->next;//!!!!!!先往后找
}
if(p1==NULL)
{
p2=p1;
p2=p1=p;//!
while(p1!=NULL)
{
p1=p1->pre;
if(i==p1->num)
{
if(p1->pre==NULL)
{
//head=p1->next;
p1->next->pre=NULL;
}
else
{
p1->pre->next=p2;
p2->pre=p1->pre;
}
consq=true;
free(p1);
p1=p2->pre;//找到一个继续找
}
else
p1=p1->pre;//!!!!!!再往前找
}
}
return consq;
}
(3)第二个动了基本都能用,这里较简单了,就不写了
- 双向链表的插入算法思想差不多,情况比删除更简单点
也可以分情况,但我就记一个通用的把
stud *insert(stud *p0,stud *p)
{
stud *p1,*p2=NULL;
p1=p0;
if(!p0) //空表
{
p0=p;
p0->next=NULL;
p0->pre=NULL;
}
else
{
if(p->num >p1->num) //向右搜索
{
while(p->num >p1->num&&p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(p->num<=p1->num)
{
p->pre=p1->pre;// 这里的指针转换省去了考虑NULL情况
p->next=p1;
p1->pre=p;
}
else
{
p1->next=p;
p->next=NULL;
}
}
else //向左搜索
{
while(p->num <p1->num&&p1->pre!=NULL)
{
p2=p1;
p1=p1->pre;
}
if(p->num>=p1->num)
{
p->next=p1->next;
p->pre=p1;
p1->next=p;
}
else
{
p1->pre=p;
p->pre=NULL;
}
}
}
return p1;
}
- 双向循环链表
- 把两个NULL改了就行
- 不写了。。。该回寝室了。。