链表的冒泡排序。

  为了练习一下链表的使用,写了个链表的冒泡排序。

冒泡排序,在每次遍历的每个链表数据中找出数据最小或最大的节点

和原始链表数据的头节点交换, 交换的过程中要用到,待交换头节点和最大或最小节点的

前驱节点。 还要注意带头节点第一个冒泡上来的数和头节点的交换。

还要注意头节点就是最小节点的前驱节点的情况。

 

// LinkListSort.cpp : 定义控制台应用程序的入口点。
//

#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;
}

posted @ 2009-03-12 21:43  smile2you  阅读(21480)  评论(0编辑  收藏  举报