插入排序C语言实现

基本思想:待排序内容被分为有序和无序两部分,从有序子列表头(尾)向后(前)考察,直至当前值不小于(不大于)无序子列表首元,此时找到插入位置,执行插入操作。
首先是数组的插入排序,我写了三个版本
#include
   
   
    
    

/* 数组的插入排序,结果为从小到大,倒序检索,允许重复值 */
void insertionSort(int a[])
{
    int i, j, k, r, temp;
    
    for(i=0,j=1;j
    
    
     
     =0 && a[k]>a[j]; k--)    /* 找寻插入位置,倒序检索,逻辑与两边的顺序应是不能交换的,若交换k=-1时,程序先判断a[k]会出错 */
            ;
        if(k < i){                            /* 若a[i]
     
     
      
      k; r--)
                a[r] = a[r-1];                /* 挪动元素 */
            a[k] = temp;                      /* 插入 */
        }
    }
}
/* 数组的插入排序,结果为从小到大,正序检索,允许重复值 */
void insertionSort(int a[])
{
    int i, j, k, r, temp;
    
    for(i=0,j=1;j
      
      
       
       k; r--)
                a[r] = a[r-1];
            a[k] = temp;
        }
    }
}
/* 数组插入排序,结果从小到大,倒序检索,不允许重复值 */
void insertionSort(int a[], int *len)
{
    int i, j, k, r, temp;
    
    for(i=0,j=1; j
       
       
         =0 && a[k]>a[j]; k--) ; if(k < i && a[k] != a[j]){ for(r=j; r>k; r--) a[r] = a[r-1]; a[k] = temp; } if(a[k] == a[j]){ for(r=j; r<(*len)-1; r++) a[r] = a[r+1]; (*len)--; } } } 
       
      
      
     
     
    
    
   
   
然后是链表的插入排序,因为使用的是单链表,故不能倒序检索。同时链表也不能像数组用下标来控制找寻插入点的循环,只能用值来判断,相等一定会推出循环,但这里的相等有两种可能:1~last中有相等的;1~last都比first小。
/* 无辅助表元,更改节点链接顺序,不更改节点内容 */
struct Node{
    int value;
    struct Node *next;
};

struct Node *insertSort(struct Node *head)
{
    struct Node *last, *first, *cur, *pre;
    
    if(head == NULL)
        return NULL;
    /* 对非空链表进行操作 */
    last = head;
    first = head->next;
    while(first != NULL){
       for(pre=NULL,cur=head; cur->value
    
    
     
     value; pre=cur,cur=cur->next)
           ;
       if(cur->value == first->value && cur != first){      /* 重复节点,删除;cur有可能与first相等此时不能执行删除 */
           last->next = first->next;
           free(first);
           first = last->next;              /* 调整无序子列表首元素位置 */
       }
       if(cur->value > first->value){
           if(pre != NULL){
               last->next = first->next;
               pre->next = first;
               first->next = cur;
               first = last->next;          /* 调整无序子列表首元素位置 */
           }
           if(pre == NULL){
               last->next = first->next;
               head = first;
               first->next = cur;
               first = last->next;         /* 调整无序子列表首元素位置 */
           }
       }else{
           last = first;                   /* 调整有序和无序子列表末元和首元的位置 */
           first = first->next;
       }
    }
    return head;
}
/* 有辅助表元,更改连接顺序, 辅助表元的存在使得头指针不会被更改,因而函数不需要返回指针值 */
void struct Node(struct Node *head)
{
    struct Node *last, *first, *cur, *pre;
    
    if(head == NULL)         
        return;
    if(head != NULL && head->next == NULL)
        return NULL;
    /* 上面一段不直接写成if(head->next == NULL) return; 是因为head若为NULL,head->next会被报错 */
    last = head->next;
    first = head->next->next;
    while(first != NULL){
        for(pre=head,cur=head->next; cur->value
     
     
      
      value; pre=cur,cur=cur->next)
            ;   
        if(cur->value == first->value && cur != first){
            last->next = first->next;
            free(first);
            first = last->next;
        }
        if(cur->value>first->value){
            last->next = first->next;
            pre->next = first;
            first->next = cur;
            first = last->next;
        }else{
            last = first;
            first = first->next;
        }
    }
}

     
     
    
    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值