您的位置:首页 > 理论基础 > 数据结构算法

改进的插入排序算法

2016-06-01 20:40 232 查看
使用数组来做插入排序时有三个过程。

第一:要在有序表中查找插入的位置。

第二: 要移动元素,以存储新的元素。

第三:插入元素。

插入元素很简单,给数组赋值就可以了,主要的优化在第一步和第二部,共有2中改进方法,分别对应第一步和第二步。

1. 折半插入排序。

       这种改进的方法主要是在上述第一步,因为是有序表,如果使用折半查找效率比顺序查找高很多。

2. 链式插入排序。

      这种改进方法在第二步,使用链表而不是数组来存储,这用就省去了移动元素的过程。

头文件定义的内容:

#define LENGTH 100   //数组最大长度,测试时可以自己修改

typedef struct Element{

    int key;

    /*other field*/

}Element;

typedef struct Node {

    Element e;

    struct Node * link;

}Node;

typedef Node * List;

//折半插入排序

void insertSort_im1(Element arr[], int n)

{

    int i;

    

    for(i = 1; i < n; i++)//依次将第i个元素插入数组

    {

        int left = 0;

        int right = i -1;

        int mid = 0;

        int j;

        Element temp = arr[i];//保存值,不然移动数组时会被覆盖

        //查找插入位置

        while(left <= right)

        {

            mid = (left + right)/2;

            if(arr[i].key >= arr[mid].key)//关键字相同时放在这能保持排序的稳定性

            {

                left = mid + 1;

            }

            else

            {

                right = mid -1;

            }                

        }

        //移动元素,存储新插入的元素,插入到right后面

        for(j = i -1; j > right; j--)

            arr[j+1] = arr[j];

        //插入

        arr[right+1] = temp;

    }

}

//链式插入排序, 链表设计成带头结点

//这个程序需要注意的地方是当传送链表指针时,需要先保存好下一个节点的连接,因为传入的参数可能会修改指针指向的内容。

void insertNode(List plist, Node * pnode)//有序表上插入一个结点

{

    Node * prev = plist;

    Node * current = prev->link;

    

    if(!pnode)

        return;

    while(current&& pnode->e.key >= current->e.key)

    {

        prev = current;

        current = current->link;

    }

    pnode->link = prev->link;

    prev->link = pnode;

}

void insertSort_im2(List plist)

{

    Node * current = plist->link;

    

    plist->link = NULL;//重置为空表,表示有序表

    while(current)

    {

        Node * temp;

        

        temp = current->link;  //需要保存下一个连接,因为下面插入结点的函数会修改current的内容

        insertNode(plist, current);

        current = temp;

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息