数据结构与算法之排序算法总结

排序算法总结

前言
本人菜鸟一枚,程序均为C++编写,如有错误,欢迎平均区指出,一定积极改正,共同学习!
7种排序算法
①冒泡排序
②选择排序
③插入排序
④快速排序
⑤归并排序
⑥基数排序
⑦堆排序
低级排序:冒泡,选择,插入
高级排序:快速排序,归并排序
1. 冒泡排序
从左向右扫描数据,选择最大的数据放到右边(n个数据扫描n-1个遍)
要点:比较相邻的两个数,如果左边的数大于右边的数就进行交换
双循环:外循环(扫描次数) 内循环(比较次数)

#include <iostream>
using namespace std;
void BubbleSort(int list[], int n);
int main()
{
 int a[] = { 1,4,2,9,5,7,3 };
 for (int i = 0; i < 7; i++)
      cout << a[i] << " ";
 cout << endl;
 BubbleSort(a, 7);
 for (int i = 0; i < 7; i++)
      cout << a[i] << " ";
 cout << endl;
 system("pause");
 return 0;
}
void BubbleSort(int list[], int n)
{
 for (int i = 0; i < n - 1; i++)
 {
  for (int j = 0; j < n - i - 1; j++)
  {
     if (list[j] > list[j + 1])
        swap(list[j], list[j + 1]);
  }
 }
}



2.选择排序
选择排序算法
比冒泡排序快一点,扫描结束后,只交换一次,放在最右边
从当前未排序的整数中找一个最小的整数,将它放在已排序的整数列表的最后
要点: 选择排序选最小的,往左边选

#include <iostream>
using namespace std;
void SelectSort(int *list, const int n);
int main()
{
	int a[] = { 1,3,5,7,2,4,6,8 };
	SelectSort(a, 8);
	for (int k = 0; k < 8; k++)
		cout << a[k] << " ";
	cout << endl;

	system("pause");
	return 0;
}
void SelectSort(int *list, const int n)
{
   for(int i=0;i<n-1;i++)
   {
       int min=i;
       for(int j=i+1;j<n;j++)
       {
          if(list[j]<list[min])
              min=j;
       }
       swap(list[i],list[min]);
   }

}

3. 插入排序
插入排序算法
用两个变量来循环,out用来循环房间里面的人,in用来循环房间外面的人,假设开始的时候有一个人出去了。

#include<iostream>
using namespace std;
template <class T>
void InsertionSort(T *a, int n);
int main()
{
	int list[] = {1,3,5,7,2,4,6,8};
	InsertionSort(list, 8);
	for (int k = 0; k < 8; k++)
		cout << list[k];
	cout << endl;
	system("pause");
	return 0;
}
template<class T>
void InsertionSort(T *a, const int n)
{
	int in, out;  //out=0这个人已经出去了a
	for (out = 1; out < n; out++)
	{
		in = out;
		T temp = a[out];
		while (in > 0 && a[in - 1] >= temp)
		{
			a[in] = a[in - 1];
			in--;
		}
		a[in] = temp;
	}
}

4. 快速排序
1.最流行的排序算法,速度最快的排序算法
2. pivot:枢轴/枢纽 (先是最左边或最右边的作为枢轴标准)小的放左边 大的放右边
3. 递归

#include<iostream>
using namespace std;


template<class T>
void QuickSort(T *a, const int left, const int right);

int main()
{
	int list[] = { 1,3,5,7,2,4,6,8,99 };
	QuickSort(list, 0, 7);
	for (int i = 0; i < 8; i++)
		cout << list[i] << endl;

	system("pause");
	return 0;
}


template<class T>
void QuickSort(T *a, const int left, const int right)
{
	if (left < right)
	{
		//选择枢轴进行划分
		int i, j;
		i = left;
		j = right + 1;
		int pivot = a[left];
		do {
			do i++; while (a[i] < pivot);
			do j--; while (a[j] > pivot);
			if (i < j)
				swap(a[i], a[j]);

		} while (i < j);
		swap(a[left], a[j]);

		QuickSort(a,left,j-1);
		QuickSort(a,j+1,right);

	}
	
}

5. 归并排序
归并排序
迭代
把两个排序好的数组归并成一个数组
把一个没有排序的数组,选两个数(当作已经排序好的数组)进行归并,归并成一个数组

#include<iostream>
#include<algorithm>
using namespace std;

void Merge(int *list, int l, int m, int h);
void MergeSort(int *list, const int l, const int h);
void Merge(int *list,  int l, int m, int h)
{
	int i = l;
	int j = m + 1;
	int k = 0;
	int *temp = new int[h - l + 1];
	while (i <= m && j <= h)
	{
		if (list[i] <= list[j])
			temp[k++] = list[i++];
		else
			temp[k++] = list[j++];
	}
	while (i <= m)
		temp[k++] = list[i++];
	while (j <= h)
		temp[k++] = list[j++];
	for (i = l, k = 0; i <= h; i++, k++)
		list[i] = temp[k];
	delete []temp;

	//copy函数 copy(a,a+n,arr)  被拷贝参数范围[a,a+n)   arr拷贝到的位置
}

//两个数组归并为一个数组
//n是一共有多少个数要合并,l和m都是数组下标
//l为要归并的数组的第一个数下标  m为要归并的数组的最后一个数下标

void MergeSort(int *List, const int l, const int h)
{
	if (l < h)
	{
		int m = l + (h - l) / 2;
		MergeSort(List, l, m);
		MergeSort(List, m + 1, h);
		Merge(List, l, m, h);
	}
	else return;
}

int main()
{
	int list[] = {0,26,5,77,1,61,11,59,15,48,19};//a[0]是不用的
	MergeSort(list, 1, 10);
	for (int k = 1; k <=10; k++)
		cout << list[k] << " ";
	cout << endl;
	system("pause");
	return 0;
}


6. 基数排序
基数排序
1.基数 十进制的基数是10,二进制的基数是2,…
2.示例
未排数组 -> 421 240 035 532 305 430 124
按个位排 -> (240 430) (421) (532) (124) (035 305)
按十位排 -> (305) (421 124) (430 532 035) (240)
按百位排 -> (035) (124) (240) (305) (421 430) (532)
()小括号把数放在一堆 实际上是把这些数放在一个链表里面

LSD最低位优先 先排低位再排高位
用链表来做 桶、箱、堆 -> 使用链表
MSD最高位优先

#include<iostream>
#include<algorithm>
#include<list>
using namespace std;
void radixsort(int data[], int n);
int maxdigit(int data[], int n);


int main()
{
	cout << "test ok!"<<endl;
	int data[10] = { 179,208,306,93,859,984,55,9,271,33 };
	radixsort(data, 10);
	for (int i = 0; i < 10; i++)
		cout << data[i] << endl;

	system("pause");
	return 0;
}


int maxdigit(int data[], int n)
{
	int d = 1;
	int p = 10;
	for (int i = 0; i < n; i++)
	{
		while (data[i] > p)
		{
			p = p * 10;
			++d;
		}
	}
	return d;
}

void radixsort(int data[], int n)
{
	int digits = maxdigit(data, n);
	int factor,d,k;
	list<int> lists[10];
	for (d=1,factor=1;d <= digits;d++,factor *= 10)
	{
		for (int i = 0; i < n; i++)
		{
			lists[(data[i] / factor) % 10].push_back(data[i]);
		}
		for (int j = k = 0; j < n; k++)
		{
			while (!lists[k].empty())
			{
				data[j++] = lists[k].front();
				lists[k].pop_front();
			}
		}
	}

}

7. 堆排序
把未排序的数据一个一个放入堆里,然后再一个一个取出来
哈希 O(1) 二叉树O(logN) 线性查找 O(N) 冒泡排序 O(N^2)
自己创建一个大顶堆
MaxHeap.h

#pragma once
#ifndef _MAXHEAP_H
#define _MAXHEAP_H
using namespace std;

template<class T>
class MaxHeap
{
public:
	MaxHeap(int mx = 10);//构造函数,默认堆的大小为10
	virtual ~MaxHeap();

	bool IsEmpty();
	void Push(const T&);
	void Pop();//把根删除
	const T& Top() const;//获取根里的数据

	void trikleUp(int index);//向上渗透
	void trikleDown(int index);//向下


private:
	T *heapArray;
	int maxSize;
	int currentSize;

};

template<class T>
MaxHeap<T>::MaxHeap(int mx)
{
	if (mx < 1) throw"max size must be >= 1";
	maxSize = mx;
	currentSize = 0;
	heapArray = new T[maxSize];
}

template<class T>
MaxHeap<T>::~MaxHeap()
{
	delete[] heapArray;
}

template<class T>
bool MaxHeap<T>::IsEmpty()
{
	return currentSize == 0;
}

template<class T>
void MaxHeap<T> ::trikleUp(int index)
{
	int parent = (index - 1) / 2;
	T bottom = heapArray[index];
	while (index > 0 && heapArray[parent] < bottom)
	{
		heapArray[index] = heapArray[parent];
		index = parent;
		parent = (parent - 1) / 2;
	}
	heapArray[index] = bottom;

}

template<class T>
void MaxHeap<T>::Push(const T& e)
{
	if (currentSize == maxSize)
		throw"MaxHeap is full";
	heapArray[currentSize] = e;
	trikleUp(currentSize);
	currentSize++;
}


template<class T>
void MaxHeap<T>::Pop()
{
	heapArray[0] = heapArray[--currentSize];
	trikleDown(0);
}


template<class T>
const T& MaxHeap<T>::Top() const
{
	return heapArray[0];
}



template<class T>
void MaxHeap<T> ::trikleDown(int index)
{
	T top = heapArray[index];//把临时的根保存起来

	int largerChild;//每个节点的两个儿子大的一个


	while (index < currentSize/2 )
	{
		int leftChild = 2 * index + 1;
		int rightChild = leftChild + 1;
		//有一种情况,只有左儿子,没有右儿子  判断右儿子
		if (rightChild < currentSize && heapArray[leftChild] < heapArray[rightChild])
			largerChild = rightChild;
		else
			largerChild = leftChild;

		if (top >= heapArray[largerChild])
			break;
		
		heapArray[index] = heapArray[largerChild];
		index = largerChild;

	}
	heapArray[index] = top;

}


#endif // !_MAXHEAP_H

把未排序的数据一个一个放入堆里,然后再一个一个取出来

#include<iostream>
#include<algorithm>
#include"MaxHeap.h"
using namespace std;
int main()
{
	cout << "test ok!" << endl;

	MaxHeap<int> h(100);
	int arr[] = { 62,3,90,27,33,8,12,9,43,66 };
	for (int i = 0; i < 10; i++)
		h.Push(arr[i]);

	for (int i = 0; i < 10; i++)
	{
		arr[i] = h.Top();
		h.Pop();
	}

	for (int i = 0; i < 10; i++)
		cout << arr[i] << endl;

	system("pause");
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值