希尔排序--自上而下的归并--自底而上的并归--快速排序--三向切分

6 篇文章 0 订阅
4 篇文章 0 订阅

代码有部分可能有重复定义,去除/**/

//头文件01.h
#pragma once
#ifndef H01
#define H01

#include<iostream>
using std::cout;
using std::cin;

const int M=10;

template <class T>
bool less(T *p, int a, int b)
{
	if (p[a] <p[b]) return 1;
	else return 0;
}


template <class T>
bool less(T a, T b)
{
	if (a<b) return 1;
	else return 0;
}


template <class T>
void show(T *a, int p)
{
	for (int i = 0; i <= p; i++)                                          //问题所在,sizeof(a)是元素长度不是数组长度?
		cout << a[i] << "  ";
	cout << std::endl;
}


template <class T>
void show(T *a, int k,int p)
{
	for (int i = k; i <= p; i++)                                          //问题所在,sizeof(a)是元素长度不是数组长度?
		cout << a[i] << "  ";
	cout << std::endl;
}


template <class T>
void change(T *a, int c, int b)
{
	T t;
	t = a[c];
	a[c] = a[b];
	a[b] = t;
}


template <class T>
void xuanze(T *p, int a, int b)
{
	int i = a;
	for (; i <= b; i++)
	{
		int min = i;
		for (int j = i + 1; j <= b; j++)
			if (p[j] < p[min])
				min = j;
		change(p, min, i);
	}
}

template <class T>
void charu(T *p, int a, int b)
{
	for (int i = 1; i <= b; i++)
		for (int j = i; j > 0 && less(p, j, j - 1); j--)
			change(p, j, j - 1);
}



template <class T>
void merge(T *p, int lo, int mid, int hi)
{
	if (hi <= lo) return;
	int i = lo, j = mid + 1;
	T temp[100];
	for (int h = lo; h <= hi; h++)
		temp[h] = p[h];
	for (int k = lo; k <= hi; k++)
	{
		if (i > mid)                       p[k] = temp[j++];
		else if (j > hi)                   p[k] = temp[i++];
		else if (less(temp[i], temp[j]))   p[k] = temp[i++];
		else                               p[k] = temp[j++];
	}
	//delete[] temp;
}


int min(int a, int b)
{
	return (a > b )? b: a;
}
#endif



//希尔排序

#include "stdafx.h"/*
#include"01.h"
#include<iostream>
using std::cout;
using std::cin;
*/
/*
int xier()                              //希尔排序
{

	int a[M];
	int i;
	for (i = 0; i < M; i++)
		a[i] = rand() % 200 + 100;
	show(a, M);
	int h = 1;
	int n = M;
	while (h < n / 3)
		h = 3 * h + 1;
	int j, k;
	while (h >= 1)                                                               //步距最小为1
	{
		for (j = h; j < M; j++)                                                  //步距h,从第h个开始比,比完往后以为开始比       
			for (k = j; k >= h && (less(a, k, k - h)); k -= h)                  //以k为基准,比较k与每k-h距离的元素的大小,可以长距离地移动元素,节省时间
			{
				change(a, k, k - h);                                                 //01.h建了一些基本函数,自底而上的并归.cpp和希尔排序.cpp都包含了头文件;结果给我报错,可是
				show(a, M);
			}
		h /= 3;
	}
	show(a, M);
	return 1;
}

*/


//自上而下的归并
#include "stdafx.h"/*
#include"01.h"
#include<iostream>
using std::cout;
using std::cin;




template <class T>
void sort(T *p, int lo, int hi)
{
	if (hi <= lo) return;
	int mid = lo + (hi - lo) / 2;
	sort(p, lo, mid);
	sort(p, mid + 1, hi);
	merge(p, lo, mid, hi);
}

 

//自上而下的并归
int binggui()                      
{
	int a[15] = { 23, 59, 89, 48, 69, 89, 99, 899, 1, 2, 3, 4, 55, 68, 19 };
	//for (int i = 0; i < 15; i++)
	//	a[i] = rand() % 300 + 100;
	show(a, 14);
	//merge(a, 0,7,14);
	sort(a, 0, 14);
	show(a, 14);
	return 1;
}*/





//自底而上的并归

#include "stdafx.h"/*
#include"01.h"
#include<iostream>
#include<ctime>
using std::cout;
using std::cin;



int binggui02()                                            //自底而上的并归
{
srand(time(0));
int a[M];// = { 23, 59, 89, 48, 69, 89, 99, 899, 1, 2, 3, 4, 55, 68, 19 };
for (int i = 0; i < M; i++)
a[i] = rand() % 300 + 100;
show(a, 14);
int i ;
int lo = 0, hi = M - 1, o = 1;
for (i = 1; i < M; i *= 2)                                      //循环时循环因子以整个并归的大小为准,而不是中值,前者容易写出结束条件
for (lo=0; lo < M - i; lo = lo + i + i)
merge(a, lo, lo + i-1, min(lo + i + i - 1, hi));                 //mid= lo + i-1,此处需要减1,设只有两个数,不减一,mid=1,调用merge时的mid=1+1=2;排序有问题
show(a, 14);
return 1;
}*/


//快速排序和三向切分


#include "stdafx.h"
#include "stdafx.h"
#include"01.h"
#include<iostream>
#include<ctime>
using std::cout;
using std::cin;
using std::endl;






template <class T>
int find(T *p, int lo, int hi)                                               //找出节点
{
	T v = p[lo];
	int i = lo, j = hi + 1;
	while (1)
	{
		while (less(p[++i], v)) if (i == hi) break;
		while (less(v,p[--j]))  if (j == lo) break;
		if (i >= j) break;
		change(p, i, j);
	}
	change(p, lo, j);
	show(p, M - 1);
	return j;
}


template <class T>                                                            //递归分类
void sort0(T *p, int lo, int hi)
{
	if (lo >= hi) return;
	int a = find(p, lo, hi);
	sort0(p, lo, a-1);
	sort0(p, a+1, hi);
}

int kuaisuchazhao()                                                           //找出一个节点,以第一个元素为基准,从两端开始比较,遇到左边比a[0]大和右边比a[0]大时,交换位置,再把a[0]放在相遇位置的合适一遍,形成左边比其小,右边比其大
{
	srand(time(0));
	int a[M];
	for (int i = 0; i < M; i++)
		a[i] = rand() % 100;
	show(a, M - 1);
	sort0(a, 0, M - 1);
	show(a,M - 1);
	cin.get();
	return 0;
}



template <class T>
void  sort(T *p, int lo, int hi)
{
	if (hi <= lo) return;
	int n=lo, m=hi, i = lo + 1; 
	while (i <= m)
	{
		if (p[i] < p[lo]) change(p, i++, n++);                   //n始终指着第一个元素,也是居中的首元素,故在下一次递归时需要“n-1”,m同理。
		else if (p[i]>p[lo]) change(p, i, m--);
		else i++;
	}
	sort(p, lo, n - 1);
	sort(p, m+1, hi);
}

int sanxiangqiefen()                                                      //三向切分法,把首元素设为中间值,开头指针n,结束指针m,通过i从左往右,碰到大的往后,小的往前。       
{
	srand(time(0));
	int a[M];
	for (int i = 0; i < M; i++)
		a[i] = rand() % 100;
	show(a, M - 1);
	sort(a, 0, M - 1);
	show(a, M - 1);
	cin.get();
	return 0;

}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值