基础学习第四弹

双向链表

  • 定义
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改了就行
    • 不写了。。。该回寝室了。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值