美文网首页
有序循环链表-插入某值-保证依然有序

有序循环链表-插入某值-保证依然有序

作者: 写代码不如跳舞 | 来源:发表于2017-08-24 16:26 被阅读0次

    问题:已知一个有序循环链表,插入一个结点值为num的结点,使循环链表依然有序。

    解法:

    如果链表为空

    1.直接插入。

    如果链表不为空

    1.声明两个指针型结点型变量p1,p2,p1指向首结点,p2指向首结点下一个结点。
    2.若待插入值num >= p1->val 并且 num<= p2->val,即插入p1与p2之间。若不符合,p1与p2依次往后移动继续比较。
    3.如果p2循环到head仍没有合适位置插入的话,此时num的值有两种情况:
    插入值比头结点的值小 或者 插入值比尾结点的值大。这影响了插入值最终插入head之后(插入值比头结点的值小)还是插入head之前(插入值比尾结点的值大)。(本题使用的是head->val=NULL,head->next为首节点的结构)

    以下附上代码,包括尾插法建立循环链表函数initListEnd(),以及解决本题的插入函数insertNum():

    #include<iostream>
    #include<cstdlib>
    using namespace std;
    
    struct LNODE
    {
        int val;
        LNODE *pnext;
    };
    
    LNODE* initListEnd(int arr[],int n) //尾插法建立循环链表,head:目标链表头结点,arr[]:插入值存放数组,n:数组长度 
    {
        
        LNODE *head = (LNODE*)malloc(sizeof(LNODE));
        head->pnext = NULL;
        
        LNODE *tmpNode; //临时结点用来存放当前arr的值
        LNODE *endNode; //始终指向目标链表尾端的节点
        
        endNode = head; //此时目标链表只有头结点 
        
        for(int i = 0 ; i < n ; ++i ) //将arr[]中的值依次依次插入链表尾端 
        {
            tmpNode = (LNODE*)malloc(sizeof(LNODE)); //为新结点申请空间 
            tmpNode->val = arr[i]; //新结点赋值 
                    
            endNode->pnext = tmpNode; //目标链表尾指向新结点
            
            endNode = endNode->pnext; //更新endNode使其指向目标结点尾端 
        }
        endNode->pnext = head; //构建循环链表
        return head;
    }
    
    void insertNum(LNODE *head,int num) //head待插入有序循环链表,num带插入值
    {
        LNODE *numNode = (LNODE*)malloc(sizeof(LNODE));
        numNode->val = num;
        if(head->pnext == NULL)//如果head为空,直接插入并构造循环链表
        {
            head->pnext = numNode;
            numNode->pnext = head;
            return ;
        }
        else//head不为空
        {
            LNODE *p1,*p2;
            p1 = head->pnext;
            p2 = head->pnext->pnext;
            int flag = 1;//flag用来记录是否在p2循环到头结点之前就已经找到合适的插入位置
                         //flag为1表示遍历整个链表后没有找到合适位置,需要进行下一步比较
            while(flag && p2!=head)
            {
                if(num >= p1->val && num<= p2->val)//成功插入链表中间
                {
                    p1->pnext = numNode;
                    numNode->pnext = p2;
                    flag = 0;
                    break;
                }
                p1 = p1->pnext;
                p2 = p2->pnext;
            }
            if(flag)//没有插入链表中间,进行下一步比较,确定num插入head之前,还是head之后。
            {
                if(p1->val <= num)
                {
                    p1->pnext = numNode;
                    numNode->pnext = p2;
                }
                else
                {
                    p2 = head->pnext;
                    head->pnext = numNode;
                    numNode->pnext = p2;
                }
            }
        }
    }
    int main()
    {
        int n = 5;
        int arr[n]={1,3,5,7,9};
        LNODE *head;
    
        head = initListEnd(arr,n);//尾插法创建循环链表
        
        cout<<"插入前:"<<endl;
        LNODE *tNode = head->pnext; //创建临时结点tNode依次输出链表各结点的值 
        while(tNode->pnext != head)
        {
            cout<<tNode->val<<" "<<endl;
            tNode = tNode->pnext;
        }
        cout<<tNode->val<<endl; //最后一个结点pnext已经为NULL了,所以循环中没有输出它,需要单独输出 
        
        insertNum(head,0);//向有序循环链表中插入值并保证依然有序
        
        cout<<"插入后:"<<endl;
        tNode = head->pnext; //创建临时结点tNode依次输出链表各结点的值 
        while(tNode->pnext != head)
        {
            cout<<tNode->val<<" "<<endl;
            tNode = tNode->pnext;
        }
        cout<<tNode->val<<endl; //最后一个结点pnext已经为NULL了,所以循环中没有输出它,需要单独输出 
        
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:有序循环链表-插入某值-保证依然有序

          本文链接:https://www.haomeiwen.com/subject/bzsedxtx.html