链表的冒泡排序



//



#include "stdafx.h"

#include "stdlib.h"



typedef int DataType;



typedef struct node

{

   DataType data;

   struct node *next;

}LinkNode;



LinkNode* Insert(DataType data,LinkNode *h);

//没有带头节点

LinkNode* CreateLinkList(int num)

{

   

   LinkNode *h;

   h=(LinkNode*)malloc(sizeof(LinkNode));

   h->next=NULL;

   return h;

}

/*

  向链表中出入数据

  参数为链表的头节点,和待插入的节点的数据

*/

LinkNode* Insert(DataType data,LinkNode *h)

{

   LinkNode *p=h,*pr;

   LinkNode *q;

  

   q=(LinkNode*)malloc(sizeof(LinkNode));



   q->data=data;  

   q->next=h->next;

   h->next=q;



  

   return h;

}

/*

显示链表的数据

*/

LinkNode* ShowLinkList(LinkNode *h)

{

    LinkNode *p=h;

    printf("\n");

    while(p!=NULL)

    {

    printf("%d-",p->data);

      p=p->next;

    }

    return h;

}



//链表实现冒泡排序- 从小到大

LinkNode* SortLinkList(LinkNode *h)

{



    LinkNode *hh=h,*pr,*p,*pp,*ppr,*temp,*ph;



    DataType min;

    int flag=1; //是否是头一次的节点

    ph=h;



    while(h!=NULL)

    {

        

    

            min=h->data;        

            p=h;

            pr=p;           

            ppr=pr;

            pp=p;

         /*

           排好顺序的链表为头节点hh开头,每次都从h节点开头的

           链表冒泡出数值最小的节点,接到hh链表开头的链表尾部。

           

         */



            //开始冒泡

            while(p!=NULL)

            {

                if(p->data<min) //找出 节点值数据最小的节点

                {    

                    ppr=pr;   //最小节点的父节点

                    pp=p;     //最小节点

                    min=p->data;  //节点的最小数值

                }

                pr=p;

                p=p->next;

            }        



           /*

             找到h节点之后,数值最小的节点, pp代表该最小节点

             ppr为pp的先驱节点

           */



            if(ppr==pp)

            {            

                h=pp;

                ph->next=h;

                if(flag==1)  //在还未建立头节点时,先建立头节点,hh代表该头节点

                {

                   hh=h;flag=0; //头节点h之前的节点都是已经按从小到达的顺序排好顺序的节点,

                }    

            }else

            {    

                /*

                 如果最小节点不是头节点p的后驱节点的话

                 就把头节点h和最小数值节点兑换

                */

                if(h!=ppr)

                {

                    /*

                      交换节点 h和pp

                      用到两个的节点的先驱节点ph和ppr

                    */

                temp=h->next;

                ppr->next=h;

                h->next=pp->next;            

                pp->next=temp;                                       

                h=pp;



                if(flag==1){hh=h;flag=0;}

                else

                {

                  ph->next=h;

                }



                }else

                {  /*

                     如果最小节点p是头节点h的后驱节点的话

                     调换两个节点

                   */

                    h->next=pp->next;

                    pp->next=h;

                    h=pp;

                    if(flag==1){hh=h;flag=0;}

                    else{

                        ph->next=pp;

                    }

                }            

                

                

        }    



        ph=h;//ph为头节点h移动时的先驱节点

        h=h->next;

    }



    



    return hh;

}



int _tmain(int argc, _TCHAR* argv[])

{

     LinkNode *h;

     h=CreateLinkList(10);

     h->data=3;

     Insert(1,h);

     Insert(2,h);

     Insert(8,h);



      Insert(3,h);

      Insert(4,h);

      Insert(5,h);

      Insert(8,h);

      Insert(5,h);

      Insert(45,h);

      Insert(40,h);

      Insert(5,h);

      

      ShowLinkList(h);



     h=SortLinkList(h);

     

     ShowLinkList(h);



    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值