最近瞎写的,判断条件过于复杂,下次用j=i+1判断条件在写一次
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
using namespace std;
#define MAXSIZE 100
int times = 0;
typedef struct hero { //定义结构体:顺序表
int ele[MAXSIZE];
int length;
}heros;
void Create(heros *&L,int a[],int n) { //顺序表创建函数
int i = 0, k = 0;
L = (heros *)malloc(sizeof(heros));
while (i < n+1) {
L->ele[k] = a[i];
k++;
i++;
}
L->length = k;
}
void operate(heros *&L, int start, int length) { //递归快速排序
int i = start + 1, j = length; //定义头指针i和尾指针j
int stander = L->ele[start]; //把数组第一个元素取出来当标准数
int temp = 0; //定义一个变量以备存放中间变量
while (i < j) { //当首指针在尾指针前面时执行
while (i < j && L->ele[i] <= stander) { //随着首指针i推移寻找比标准数大的元素
i++;
}
while (i<j && L->ele[j] > stander) { //随着尾指针j推移寻找比标准数大的元素
j--;
}
if (i < j) { //交换首指针指向的大元素和尾指针指向的小元素
temp = L->ele[i];
L->ele[i] = L->ele[j];
L->ele[j] = temp;
}
}
if (i == j) { //当首位指针碰头
if (i == start + 1) { //第一种情况:i指针停在第一个位置和j相遇
if (L->ele[i] < L->ele[start]) { //第一个数比基准数小,这是因为这个子问题一共就2个元素
L->ele[start] = L->ele[i]; //交换基准数和第一个数
L->ele[i] = stander;
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
}
else if (L->ele[i] >= L->ele[start]) { //第一个数比基准数大或相等,说明标准数就是最小的了,就排第一个
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;//不做交换
if (length - 1 > 0) { //如果这个数组不止2个元素,就还得对后面的数排序
operate(L, start + 1, length);
}
}
}
else if (i == length) { //第二种情况:i指针在最后一个位置和j相遇;由于只有2个元素的情况在上一个i==start+1的if条件下处理完毕了,所以不用担心这种特殊情况对这里造成越界之类的影响
if (L->ele[i] < L->ele[start]) { //最后一个数比基准数小,说明前面的数都比基准数小,首指针才可能移动到末尾
L->ele[start] = L->ele[i]; //直接交换基准数和末尾元素,这样一来前面的数都比基准数小了
L->ele[i] = stander;
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
operate(L, start, length - 1); //最后一个确定了,前面的还得排
}
else if (L->ele[i] >= L->ele[start]) { //最后一个数比基准数大或相等,例如7,1,1,1,10这种情况,i和j在末尾相遇
L->ele[start] = L->ele[i - 1]; //此时应该将末尾数前一个数与基准数交换,例如7,1,1,1,10变为1,1,1,7,10
L->ele[i - 1] = stander; //由于只有2个元素的情况在上一个i==start+1的if条件下处理完毕了,所以不用担心这种特殊情况对这里造成越界之类的影响
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
operate(L, start, length - 2); //最后两个确定了,前面的还得排
}
}
else { //第三种情况:指针在数组中间相遇,最正常的情况
if (L->ele[i] < L->ele[start]) { //相遇在了一个比基准数小的数
L->ele[start] = L->ele[i];
L->ele[i] = stander; //直接把这个数和基准数互换
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
if ((i - 1 - start) > 0) { //左子问题
operate(L, start, i - 1);
}
if ((length - i - 1) > 0) { //右子问题
operate(L, i + 1, length);
}
}
else if (L->ele[i] >= L->ele[start]) { //相遇在了一个比基准数大或者相等的数
L->ele[start] = L->ele[i - 1];
L->ele[i - 1] = stander; //把相遇位置前一个数跟基准数互换
times++;
cout << "经过第" << times << "次排序后:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
if ((i - 2 - start) > 0) { //左子问题
operate(L, start, i - 2);
}
if ((length - i - 1) > 0) { //右子问题
operate(L, i, length);
}
}
}
}
}
template <class T> //求和函数模板(函数模板案例)
T sum(T a[], int n) {
T this_sum = 0;
for (int i = 0;i < n;i++) {
this_sum = this_sum +a[i];
}
return this_sum;
}
int main(int argc,char *argv[]) {
heros *L;
int a[10] = {123,135,3,246,24,243,52,354,34,21};
int n = 9;
int count = 0;
Create(L, a, n); //建表
cout << "排序前数组顺序为:" << endl;
for (int i = 0;i < L->length;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
cout << "求和结果:" << sum(L->ele,10) << endl; //排序前求和
operate(L,0,9); //进行快速排序
cout << "排序后数组顺序为:" << endl;
for (int i = 0;i < 10;i++) {
cout << L->ele[i] << " ";
}
cout << endl;
cout << "求和结果:" << sum(L->ele, 10) << endl; //比较两次求和结果,相当于初步检查数组中元素经过排序有无变化
system("PAUSE");
}