插入排序法之——直接插入排序、折半插入排序、希尔排序

// test20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<string.h>
#include<deque>
#include <forward_list>

using namespace std;

class Solution {
public:
	void InsertSort(vector<int> &vec)//直接插入排序
	{
		for (int i = 1;i < vec.size();++i)//从第二个数开始进行直接插入排序
		{
			int num = vec[i];
			
			int flag = -1;//如果flag==-1,则是没有找到比num大的数,所以位置保持不变
			for (int j = 0;j < i;++j) 
			{
				if (num < vec[j])//在前i个数中找到大于或等于num的数,插入到第一个大于num的数前面
				{
					flag = j;
					break;
				}
			}
	//		for (flag;flag <= i;++flag)
			if (flag == -1) continue;//用continue,而不是break,结束本次循环,执行下次循环
			while (i > flag)
			{
				
				vec[i] = vec[i-1];
				i--;
			}
			vec[flag] = num;
		}
		print(vec);
	}

	void BInsertSort(vector<int> &vec)
	{
		for (int i = 1;i < vec.size();++i)
		{
			int num = vec[i];
		
			int flag = -1;//大于num的节点位置,即插入num的位置
			int low = 0;  //用折半查找发找到第一个大于num的节点位置
			int high = i;
			int mid = (low + high) / 2;
			while (low <= high)
			{
				if (num >= vec[mid])//要找到第一个大于num的位置,注意这里的等于号!!!!!!!!!!!!!!!
				{
					low = mid + 1;
					mid = (low + high) / 2;
				}
				else 
				{
					high = mid - 1;
					mid = (low + high) / 2;
				}
			}
			//如果high==i,就是没找到大于num的数,不用移动
			//如果low==0,就是要把num插入最前面
			//如果不符合上述两个条件,则把节点插入到low前面
			if(high==i)continue;
			else flag = low;

		//	if (flag == -1) continue;
			while (i>flag)
			{
				vec[i] = vec[i - 1];
				--i;
			}
			vec[flag] = num;
		}

		print(vec);
	}

	void ShellInsertSort(vector<int> &vec)
	{
		SheellSort(vec,1);
	}
	//希尔排序要设置排序间隔
	void  SheellSort(vector<int> &vec,int dk)//分成dk组,每一组进行直接插入排序
	{
		for (int i = dk;i < vec.size();++i)//从第二个数开始判断
		{
			int num = vec[i];
		
			
			int flag = -1;
			int j = i - dk;
			for (j;j >=0;j -= dk)//从0号单元开始比较,依次往后比较,找到第一个小于num的数字,插入其后面
			{//如果没有找到,则fla==-1,插入到最前面
				if (num >= vec[j])//如果flag==j,则不用做处理
				{
					flag = j;
					break;
				}
			}
			
			if (flag == -1)
			{
				while (i>j+dk)
				{
					vec[i] = vec[i-dk];
					i = i - dk;
				}
				vec[j + dk] = num;
				
			}

			else
			{
				while (i>flag + dk)
				{
					vec[i] = vec[i - dk];
					i = i - dk;
				}
				vec[flag + dk] = num;
			}
		}
		print(vec);
	}

	void print(vector<int> &vec)//打印数据
	{
		for (auto it = vec.begin();it != vec.end();++it)
		{
			cout << *it << "  ";
		}
		cout << endl;
	}

};
int main()
{
//	vector<int> vec = { 1,3,2,7,6,5,4,8,9 };
//	vector<int> vec = { 1,3,2};
	vector<int> vec = { 49,38,65,97,76,13,27,49,55,4};
	//vector<int> vec = { 49,38,65,97,76,13,27,55,4 };
	Solution so;
	//原来的序列
	cout << "原来的序列:   ";
	so.print(vec);
	//直接插入排序:
	cout << "直接插入排序:";
	 so.InsertSort(vec);
	//折半排序
	cout << "折半插入排序:";
	so.BInsertSort(vec);
	//希尔排序
	cout << "希尔排序:";
	so.ShellInsertSort(vec);


	return 0;
}
原文地址:https://www.cnblogs.com/wdan2016/p/6044792.html