改进的插入排序算法
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;
}
}
第一:要在有序表中查找插入的位置。
第二: 要移动元素,以存储新的元素。
第三:插入元素。
插入元素很简单,给数组赋值就可以了,主要的优化在第一步和第二部,共有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;
}
}
相关文章推荐
- 插入排序
- MySQL 优化
- Google排名优化的几个影响因素
- DB2优化(简易版)
- Mysql limit 优化,百万至千万级快速分页 复合索引的引用并应用于轻量级框架
- C#中尾递归的使用、优化及编译器优化
- 对优化Ruby on Rails性能的一些办法的探究
- C#数据结构之顺序表(SeqList)实例详解
- 优化Ruby脚本效率实例分享
- Lua教程(七):数据结构详解
- Asp编码优化技巧
- 如何监测和优化OLAP数据库
- mysql -参数thread_cache_size优化方法 小结
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 深入学习SQL Server聚合函数算法优化技巧
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- MySQL常见的底层优化操作教程及相关建议
- 详解mysql的limit经典用法及优化实例