1冒泡排序
改进1 添加sorted 表示是否已经排序
void bubbleSort(vector<int>& array) {
int n = array.size() ;
for (int i = 0; i < n - 1;i++){
int sorted = true;
for (int j = 0; j < n - i - 1;j++){
if(array[j]>array[j+1])
{
swap(array[j], array[j + 1]);
sorted = false;
}
}
if(sorted){
break;
}
}
}
假设每趟都是有序,如果发生交换则表示无序,同时记录最后一次发生交换的下标,内层循环最大值就是它
void bubbleSort(vector<int>& array) {
int n = array.size();
int secondCount = n-1;
for (int i = 0; i < n-1;i++){
bool sorted = true;
int lastChangeIndex = 0;
for (int j = 0; j <secondCount ;j++){
if(array[j]>array[j+1]){
swap(array[j],array[j+1]);
sorted = false;
lastChangeIndex = j;
}
}
if(sorted){
break;
}
secondCount = lastChangeIndex;
}
}
2 选择排序
void selectionSort(vector<int>& array) {
int n = array.size();
for (int i = 0; i < n-1; i++)
{
int minIndex = i;
for (int j = i; j < n; j++)
{
if (array[j] < array[minIndex]) //找到最小的数
minIndex = j; //将最小数的索引保存
}
if(i!=minIndex)
swap(array[i], array[minIndex]);
}
}
3 插入排序
void insertsort1(vector<int>& array) {
int n = array.size();
for (int i = 1; i < n; i++)
{
int cur = i;
while(cur>0&&(array[cur]<array[cur-1])){
swap(array[cur], array[cur - 1]);
cur--;
}
}
}
优化一 将其中的交换改为挪动
void insertsort2(vector<int>& array) {
int n = array.size();
for (int i = 1; i < n; i++)
{
int cur = i;
int value = array[i];
while(cur>0&&(value<array[cur-1])){
array[cur] = array[cur - 1];
cur--;
}
array[cur] = value;
}
}
优化二 在之前的算法中 我们是需要在有序序列中选择一个合适的位置进行插入 然后将之后的有序序列往后移动。在这里我们对于位置的插入可以采用二分查找的策略
int search (vector<int>& array,int index ){
int begin = 0;
int end = index;
int val = array[index];
while(begin<end){
int mid = (begin + end) >> 1;
if(val<array[mid]){
end = mid;
}
else{
begin = mid + 1;
}
}
return begin;
}
void insertsort3(vector<int>& array) {
int n = array.size();
for (int i = 1; i < n; i++)
{
int pos = search(array, i);
int val = array[i];
for (int j = i; j > pos;j--){
array[j] = array[j - 1];
}
array[pos] = val;
}
}
总结下二分查找
int search (vector<int>& array,int val ){
int begin = 0;
int end = array.size();
while(begin<end){
int mid = (begin + end) >> 1;
//注意此处是<= 如果和要插入的数相等的数有好几个, 是插在最右边的位置
if(val<array[mid]){
end = mid;
}
else{
begin = mid + 1;
}
}
return begin;
}
int main(){
vector<int> v{1,2,3,4,4,4,5,6,8};
cout<<search(v,0)<<endl; //0
cout<<search(v,1)<<endl; //1
cout<<search(v,4)<<endl; //6
cout<<search(v,5)<<endl; //7
cout<<search(v,7)<<endl; //8
cout<<search(v,9)<<endl; //9
cout << endl;
}
int search (vector<int>& array,int val ){
int begin = 0;
int end = array.size();
while(begin<end){
int mid = (begin + end) >> 1;
//注意此处是<= 如果和要插入的数相等的数有好几个, 是插在最左边的位置
if(val<=array[mid]){
end = mid;
}
else{
begin = mid + 1;
}
}
return begin;
}
int main(){
vector<int> v{1,2,3,4,4,4,5,6,8};
cout<<search(v,0)<<endl; //0
cout<<search(v,1)<<endl; //0
cout<<search(v,4)<<endl; //3
cout<<search(v,5)<<endl; //6
cout<<search(v,7)<<endl; //8
cout<<search(v,9)<<endl; //9
cout << endl;
}
找到的话输出位置,没找到输出-1
int search (vector<int>& array,int val ){
int begin = 0;
int end = array.size();
while(begin<end){
int mid = (begin + end) >> 1;
if(val<array[mid]){
end = mid;
}
else if(val>array[mid]){
begin = mid + 1;
}
else{
return mid;
}
}
return -1;
}
int main(){
vector<int> v{1,2,3,4,4,4,5,6,8};
cout<<search(v,0)<<endl; //-1
cout<<search(v,1)<<endl; //0
cout<<search(v,4)<<endl; //4
cout<<search(v,5)<<endl; //6
cout<<search(v,7)<<endl; //-1
cout<<search(v,9)<<endl; //-1
cout << endl;
}
int search (vector<int>& array,int val ){
int begin = 0;
int end = array.size()-1;//改动的地方
while(begin<=end){
int mid = (begin + end) >> 1;
if(val<array[mid]){
end = mid-1;
}
else if(val>array[mid]){
begin = mid + 1;
}
else{
return mid;
}
}
return -1;
}
int main(){
vector<int> v{1,2,3,4,4,4,5,6,8};
cout<<search(v,0)<<endl; //-1
cout<<search(v,1)<<endl; //0
cout<<search(v,4)<<endl; //4
cout<<search(v,5)<<endl; //6
cout<<search(v,7)<<endl; //-1
cout<<search(v,9)<<endl; //-1
cout << endl;
}
4快速排序
void quicksort(vector<int> &v, int left,int right) {
if(left<right){
int pivot = v[left];
int low = left, high = right;
while(low<high){
while(low<high){
if(v[high]>pivot){
high--;
}else{
v[low++] = v[high];
break;
}
}
while(low<high){
if(v[low]<pivot){
low++;
}else{
v[high--] = v[low];
break;
}
}
}
v[low] = pivot;
quicksort(v, left, low - 1);
quicksort(v, high + 1, right);
}
}
5希尔排序
希尔排序的步长可以自己设置
void shellSort(vector<int>&a,int len)
{
int step = len >> 1;//设置步长
while(step) // while gap>=1
{
//这里是插入排序
for (int col = 0; col < step;++col){
for (int begin = col + step; begin < len; begin += step){
int cur = begin;
while (cur>col&&a[cur]<a[cur-step]){
swap(a[cur], a[cur - step]);
cur -= step;
}
}
}
step = step >> 1;
}
}
6计数排序
void countSort(vector<int>&a)
{
int len = a.size();
int min = a[0], max = a[0];
for (int i = 1; i < len;i++){
if(a[i]>max)
max = a[i];
if(a[i]<min)
min = a[i];
}
vector<int> count(max-min+1);
for (int i = 0; i < len;i++){
count[a[i] - min]++;
}
for (int i = 1; i < count.size();i++){
count[i] += count[i - 1];
}
vector<int> res(len);
for (int i = len - 1; i >= 0;i--){
res[--count[a[i] - min]] = a[i];
}
for (int i = 0; i < len;i++){
a[i] = res[i];
}
}
此外还有归并排序 推排序 桶排序 基数排序