简单的排序算法(插入排序法、冒泡排序法、选择排序法)

来源:互联网 发布:欧洲十国游 知乎 编辑:程序博客网 时间:2024/06/05 17:42

1.插入排序法

算法思想:

(1)将开头元素视为已排序
(2)执行以下三个步骤,知道所有的元素排序完毕
        首先取出未排序部分的第一个元素将其赋值给全局变量v。
        在已经排序完成的部分,将所有比v大的一个元素向后移动一个单位。
        将变量v中保存的值插入到移动后的空位中,此时已排序部分的元素增加一个而未排序部分的元素减少一个。

核心代码:



利用了二重循环:
循环变量i表示未排序部分的开始元素,每次循环一次就将这个元素插入到合适的位置。
全局变量v用于临时保存数组A[i]的值。
循环变量j从第i个元素向前(即已排序部分)寻找,当已排序部分的值大于v时就将这个元素向后移动一位,当找到第一个不大于v的值或者j<0时则跳出循环,并把v插入到当前j+1位置。

运行结果:

2.冒泡排序法

算法思想:

      重复执行下述处理,直到数组中不包含相反元素的相邻元素
(1)从数组末尾开始依次比较两个相邻元素,如果大小相反则交换位置。

核心代码:

利用flag标志的冒泡排序


也是利用了二重循环:
循环变量i表示未排序部分的开始元素,从数组开头向末尾移动
循环变量用于对未排序部分中的相邻元素两两比较,从A的末尾N-1开始,减少到i+1结束
变量flag用于标志是否存在顺序相反的相邻元素

运行结果:



3.选择排序法

算法思想:

重复执行N-1次下述处理:
(1)找出未排序部分最小值的位置minj
(2)将minj位置的元素与未排序部分的起始元素交换

核心代码:




同样也是利用了双重循环:
       外层循环变量i表示未排序部分的开头元素,用于将循环变量从开头向末尾移动
       循环变量j用来查找未排序部分最小值的位置(即minj)
       变量minj用于在循环处理中寻找从i到N-1中最小值的位置
注意:内层循环只用来寻找最小值的位置,而将最小值(minj)与A[i]的值交换是在外层循环中实现的

运行结果:


总结:

       第一次认认真真的来学有关于算法的问题,虽然参考书上讲的已经很清楚了但是自己对照讲解与代码理解还是有点晕,自己按照这三种算法写了以后发现三种排序都是用了二重循环来实现的,看起来似乎差别不大,但是仔细想想三种排序的思想确实不一样,这三种排序我已经反反复复对照书和代码看了三遍还是有些迷糊,所以就写下来,等以后用到的时候再进一步的理解与掌握。

附源代码:
1.插入排序法
#include <iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int A[100];
int N,v;
void insertionSort(int A[], int N);
void print(int A[], int N);
int main()
{
cout << "请输入数组长度N:" << endl;
cin >> N;
for (int i = 0; i < N; i++)
{
// scanf("%d", &A[i]);
cin >> A[i];
}
cout << "插入排序结果:" << endl;
insertionSort(A, N);
}
void insertionSort(int A[], int N)
{
for (int i = 0; i < N; i++)
{
v = A[i];
int j = i - 1;
while (j >= 0 && A[j]>v)
{
A[j + 1] = A[j];//将大于A[i]的部分向后移动一位
j--;
}
A[j + 1] = v;
print(A, N);
}
}
void print(int A[], int N)
{
for (int i = 0; i < N; i++)
{
if (i >0)
{
cout << " ";
}
cout << A[i];

}
cout << endl;
}
/*scanf  ();
格式输入函数
需要 #include<stdio.h>    //标准输入输出头文件
格式
scanf("格式控制字符串",地址列表);
例子
scanf("%d %f",&a,&b);
前面 %d  表示 第一个 输入数据 为 十进制
       %f  表示  第二个输入数据为  浮点数
        &a 表示 a的地址
      &b 表示 b的 地址
&a[i] 为一维数组的地址*/
2.冒泡排序法
#include<iostream>
using namespace std;
int A[100];
int N;
void bubbleSort(int A[], int N);
int times=0;
int temp;
int main()
{
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> A[i];
}

bubbleSort(A, N);
for (int i = 0; i < N; i++)
{
cout<<A[i];
if (i != N - 1)
cout << " ";
}
cout << endl;
cout << times<<endl;
}
void bubbleSort(int A[], int N)
{
int flag = 1;//存在顺序相反的相邻元素
int i = 0;//未排序部分的起始下标
while (flag)
{
flag = 0;
for (int j = N - 1; j >= i + 1; j--)
{
if (A[j] < A[j - 1])
{
temp=A[j];
A[j] = A[j - 1];
A[j - 1] = temp;
times++;
}
flag = 1;//每次交换完相邻的两个数就将标志置为1,然后继续向前比较
}
i++;
}
}
3.选择排序法
#include <iostream>
using namespace std;
int A[100], N, times = 0;
void selectionSort(int A[], int N);
void print(int A[], int N);
int main()
{
cin >> N;
for (int i = 0; i < N; i++)
cin >> A[i];
selectionSort(A, N);
print(A, N);


}
void selectionSort(int A[], int N)
{
int temp = 0;
int minj;//每轮循环处理中,第i号到第N-1号元素中最小值的位置
for (int i = 0; i < N; i++)//循环变量i表示未排序部分的开头元素,从数组开头向末尾移动
{
minj = i;
for (int j = i; j < N; j++)
{
if (A[j] < A[minj])
minj = j;
}
temp = A[i];
A[i] = A[minj];
A[minj] = temp;
if (minj != i)
times++;
}
//print(A, N);
}
void print(int A[], int N)
{
for (int i = 0; i < N; i++)
{
cout << A[i];
if (i != N - 1)cout << " ";
}
cout << endl << times<<endl;
}





1 0
原创粉丝点击