数据结构之——插入排序

1.排序中一些概念

(1)算法稳定性:如果待排序的序列中两个元素A和B,对应的关键字key_A和key_B相等,且在原序列中A在B前面。如果使用某一排序算法后,A仍在B前面,则称这个算法是稳定的,否则称该算法不稳定。值得注意的是,排序算法稳定与否并不能衡量一个算法的优劣,主要是用其来描述算法的性质。

(2)在排序过程中,根据数据元素是否完全在内存中,可以及将算法分为内部排序和外部排序。如果排序期间元素全部在内存中,则称之为内部排序;若排序期间元素无法全部同时放入内存中,则将其称之为外部排序。

2.三种插入排序算法的实现

  1 #include<iostream>
  2 using namespace std;
  3 //声明打印辅助函数
  4 void printArray(int array[], int length);
  5 //声明直接插入排序函数
  6 void InsertionSort(int array[], int length);
  7 //定义折半插入排序函数
  8 void SplitHalfInsertionSort(int array[], int length);
  9 //定义希尔排序
 10 void ShellSort(int array[], int length);
 11
 12 int main()
 13 {
 14     int array[] = { 12, 3, 6, 4, 27, 9 };
 15     int length = sizeof(array) / sizeof(*array);
 16     cout << "排序前序列为:" << endl;
 17     printArray(array, length);
 18     InsertionSort(array, length);
 19     cout << endl << "直接插入排序排序后序列为:" << endl;
 20     printArray(array, length);
 21     cout << endl;
 22     SplitHalfInsertionSort(array, length);
 23     cout << endl << "折半插入排序排序后序列为:" << endl;
 24     printArray(array, length);
 25     cout << endl;
 26     ShellSort(array, length);
 27     cout << endl << "Shell插入排序排序后序列为:" << endl;
 28     printArray(array, length);
 29     cout << endl;
 30     system("pause");
 31     return 0;
 32 }
 33
 34 void printArray(int array[], int length)
 35 {
 36     for (int i = 0; i < length;i++)
 37     {
 38         if (i == length - 1)
 39             cout << array[i];
 40         else
 41             cout << array[i] << ",";
 42     }
 43 }
 44
 45 void InsertionSort(int array[], int length)
 46 {
 47     //直接从1号元素开始,加快速度
 48     for (int i = 1; i < length;i++)
 49     {
 50         int p = i;
 51         //记录要插入元素
 52         int tmp = array[i];
 53         for (int j = i - 1; j >=0 ; j--)
 54         {
 55             if (array[j]>tmp)
 56             {
 57                 array[j + 1] = array[j];
 58                 //记录待插入的位置
 59                 p = j;
 60             }
 61         }
 62         //在正确位置插入元素
 63         array[p] = tmp;
 64     }
 65 }
 66
 67 void SplitHalfInsertionSort(int array[], int length)
 68 {
 69     //直接从1号元素开始,加快速度
 70     for (int i = 1; i < length; i++)
 71     {
 72         int mid, low = 0, high = i;
 73         //记录要插入元素
 74         int tmp = array[i];
 75         while (low<=high)
 76         {
 77             mid = (low + high) / 2;
 78             if (array[mid]>tmp)
 79             {
 80                 high = mid - 1;
 81             }
 82             else
 83             {
 84                 low = mid + 1;
 85             }
 86         }
 87         for (int j = i - 1; j >= high ;j--)
 88         {
 89             array[j + 1] = array[j];
 90         }
 91         //在正确位置插入元素
 92         array[high] = tmp;
 93     }
 94 }
 95
 96 void ShellSort(int array[], int length)
 97 {
 98     int gap = length;
 99     do
100     {
101         gap = gap / 3 + 1;//经验取值
102         for (int i = gap; i<length; i += gap)
103         {
104             int k = i;
105             int tmp = array[k];
106             for (int j = i - gap; (j >= 0) && (array[j]>tmp); j -= gap)
107             {
108                 array[j + gap] = array[j];
109                 k = j;
110             }
111             array[k] = tmp;
112         }
113     } while (gap > 1);
114 }

3.插入排序讨论

(1)在待排序的元素基本有序的前提下,直接插入排序是效率最高的排序算法。

(2)对于同一待排序序列,折半插入排序和直接插入排序的差别在于元素的比较次数。

(3)在最后一趟开始之前,所有的元素可能都不在最终位置上的直接插入排序。

(4)希尔排序是不稳定算法,另外两个插入算法是稳定算法。

时间: 2024-12-19 04:01:25

数据结构之——插入排序的相关文章

数据结构例程——插入排序之希尔排序

本文是[数据结构基础系列(9):排序]中第3课时[插入排序之希尔排序]的例程. 1.希尔排序 #include <stdio.h> #define MaxSize 20 typedef int KeyType; //定义关键字类型 typedef char InfoType[10]; typedef struct //记录类型 { KeyType key; //关键字项 InfoType data; //其他数据项,类型为InfoType } RecType; //排序的记录类型定义 void

数据结构—排序-----插入排序

插入排序,就是对一个已经排序好 的数组中插入元素, 比如{2,3,1,4,5},这5个元素组成的数组,我们现在要对他们进行排序,首先,我们把{2}看成已经排序好的数组,然后,把3 这个元素插入到已经排序好的{2} 的数组中,于是就会有{2,3},然后,再把1插入到{2,3}已经排序好的数组中,这个时候,1这个元素与已经排序好的数组中的每一个元素进行对比,直到找到这个元素的位置. 后面的一次类推: 下面先把代码贴出来:(完全复制,可以运行)这里使用的是VC++6.0 编译环境,使用c语言:

c语言数据结构之 插入排序

算法:从第二个元素开始,与前一个元素进行比较,如果小于前一个元素,两者交换位置,一直循环到不再小为止 编译器:VS2013 代码 #include "stdafx.h"#include<stdlib.h> //函数声明void InsertSort(int a[],int n); //插入排序(从小到大) int main(){ int i,n,a[100]; printf("请输入需要排序元素的个数:"); scanf_s("%d"

数据结构之插入排序与希尔排序

1.直接插入排序 直接插入排序是一种最简单的排序算法,它的基本操作是将一个记录插入到已经排序好的序列中,从而得到一个新的有序表.直接插入排序算法原理如下图所示: 直接插入排序算法如下: void InsertSort(int arr[],int length) { int key,j; for(int i=1;i<length;++i) { key=arr[i]; //记录标志; j=i-1; //循环比较并且交换相邻的两个数; while (j>=0&&arr[j]>k

数据结构之插入排序--折半插入排序

排序思路:通过折半查找的方式找到合适的插入位置再插入. 算法实现: public class BiInsertSort { public static void biInsertSort(int arr[]){ for(int i = 1; i < arr.length; i ++){ int temp = arr[i]; int left = 0; int right = i-1; while(left <= right){//通过拆装查找找到插入位置 int mid = (left+rig

数据结构之插入排序--直接插入排序

排序思路:每次将一个待排序的元素与已排序的元素进行逐一比较,直到找到合适的位置按大小插入. 第一趟比较示图: 算法实现: public static void insertsort(int arr[]){ for(int i = 1;i < arr.length; i ++){ if(arr[i] < arr[i-1]){//注意[0,i-1]都是有序的.如果待插入元素比arr[i-1]还大则无需再与[i-1]前面的元素进行比较了,反之则进入if语句 int temp = arr[i]; in

[golang] 数据结构-直接插入排序

原理直接插入排序,也是一种非常简单的排序算法.第一轮先从第二个元素开始,和第一个比较,如果较小就交换位置,本轮结束.第二轮从第三个元素开始,先与第二个比较,如果较小就与第二个交换,交换后再于第一个比较.如此循环直至最后一个元素完成比较逻辑. 复杂度最好的情况下,直接插入排序只需进行n-1次比较,0次的交换.平均下来时间复杂度为 O(n^2).由于是每个元素逐个与有序的队列进行比较,所以不会出现相同数值的元素在排序完成后交换位置.所以直接插入排序是种稳定的排序算法. 代码 package main

[golang] 数据结构-二分插入排序

接上文 直接插入排序直接插入排序每轮比较中,都需要把待处理的元素与前面每一位元素进行比较.那么有没有一种方法可以优化下,减少比较次数呢?答案当然是有的,下面介绍的二分插入就是直接插入排序的优化算法之一. 原理直接插入排序是挨个的去比较,而二分插入排序则是利用二分搜索的原理,将待排序的元素与左侧已经排好序的队列的中间元素(n/2)进行比较.较小时则继续与中间元素左侧队列中间元素进行比较,较大则与中间元素右侧队列的中间元素进行比较,直至找到合适的位置,再讲这个位置后续的元素向后移动一位,带插入的元素

golang数据结构之插入排序

//InsertSort 插入排序 func InsertSort(arr *[7]int) { for i := 1; i < len(arr); i++ { insertVal := (*arr)[i] inserIndex := i - 1 for inserIndex >= 0 && (*arr)[inserIndex] > insertVal { (*arr)[inserIndex+1] = (*arr)[inserIndex] inserIndex-- } /