链表的冒泡排序。

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

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

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

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

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

 

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

转载于:https://www.cnblogs.com/smile2you/archive/2009/03/12/1409982.html

你可能感兴趣的:(链表的冒泡排序。)