281 lines
6.2 KiB
C++
281 lines
6.2 KiB
C++
#include <random>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <ctime>
|
|
using namespace std;
|
|
//#define CONT
|
|
//#define COUT_LIST
|
|
|
|
struct LinkNode{
|
|
int data;
|
|
LinkNode* next;
|
|
};
|
|
|
|
#ifdef CONT
|
|
long long int cont_if = 0;
|
|
long long int cont_change = 0;
|
|
#endif
|
|
|
|
#ifdef COUT_LIST
|
|
void coutList(LinkNode* head){
|
|
head = head->next;
|
|
while (head){
|
|
cout << head->data << " ";
|
|
head = head->next;
|
|
}
|
|
cout << endl;
|
|
}
|
|
#endif
|
|
|
|
LinkNode* initArandList(int num){
|
|
LinkNode* head = nullptr;
|
|
default_random_engine generator((unsigned)clock());
|
|
uniform_int_distribution<int> dis(0,10000);
|
|
auto dice = bind(dis,generator);
|
|
dice();
|
|
for(int i=0;i<num;i++)
|
|
head = new LinkNode{dice(),head};
|
|
return new LinkNode{0,head};
|
|
}
|
|
LinkNode* initLinkList(int num){
|
|
LinkNode *head = nullptr;
|
|
for(int i = 0;i<num;i++){
|
|
head = new LinkNode{i,head};
|
|
}
|
|
return new LinkNode{0,head};
|
|
}
|
|
LinkNode* initReList(int num){
|
|
LinkNode *head = nullptr;
|
|
for(int i = num;i>0;i--){
|
|
head = new LinkNode{i,head};
|
|
}
|
|
return new LinkNode{0,head};
|
|
}
|
|
void InsertSort(LinkNode* in) {
|
|
#ifdef CONT
|
|
cont_if = 0;
|
|
cont_change = 0;
|
|
#endif
|
|
LinkNode *h1 = nullptr, *h2 = nullptr, *h3 = nullptr;
|
|
h3 = in;
|
|
h2 = in->next;
|
|
while (h2) {
|
|
h1 = in;
|
|
#ifdef CONT
|
|
cont_change += 1;
|
|
#endif
|
|
while (h1 != h2) {
|
|
#ifdef CONT
|
|
cont_if++;
|
|
#endif
|
|
if (h1->next->data > h2->data) {
|
|
h3->next = h2->next;
|
|
h2->next = h1->next;
|
|
h1->next = h2;
|
|
h2 = h3->next;
|
|
#ifdef CONT
|
|
cont_change += 4;
|
|
#endif
|
|
#ifdef COUT_LIST
|
|
coutList(in);
|
|
#endif
|
|
break;
|
|
}
|
|
h1 = h1->next;
|
|
#ifdef CONT
|
|
cont_change += 1;
|
|
#endif
|
|
}
|
|
if (h1 == h2) {
|
|
h2 = h2->next;
|
|
h3 = h3->next;
|
|
#ifdef CONT
|
|
cont_change += 2;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
void BubbleSort(LinkNode* in){
|
|
#ifdef CONT
|
|
cont_if = 0;
|
|
cont_change = 0;
|
|
#endif
|
|
LinkNode *end= nullptr,*head;
|
|
int tmp = 0;
|
|
while(end != in->next){
|
|
head= in->next;
|
|
while (head->next != end){
|
|
if(head->data > head->next->data){
|
|
#ifdef CONT
|
|
cont_change +=3;
|
|
#endif
|
|
tmp = head->data;
|
|
head->data = head->next->data;
|
|
head->next->data = tmp;
|
|
#ifdef COUT_LIST
|
|
coutList(in);
|
|
#endif
|
|
}
|
|
head = head->next;
|
|
#ifdef CONT
|
|
cont_if ++;
|
|
cont_change +=1;
|
|
#endif
|
|
}
|
|
end = head;
|
|
#ifdef CONT
|
|
cont_change +=2;
|
|
#endif
|
|
}
|
|
}
|
|
void SelectionSort(LinkNode *in){
|
|
#ifdef CONT
|
|
cont_if = 0;
|
|
cont_change = 0;
|
|
#endif
|
|
LinkNode *end=in,*head,*beformin = nullptr,*tmp;
|
|
while (end->next->next){
|
|
beformin = end;
|
|
head = end;
|
|
while (head->next){
|
|
if(head->next->data < beformin->next->data){
|
|
#ifdef CONT
|
|
cont_change ++;
|
|
#endif
|
|
beformin = head;
|
|
}
|
|
#ifdef CONT
|
|
cont_if ++;
|
|
cont_change ++;
|
|
#endif
|
|
head = head->next;
|
|
}
|
|
#ifdef CONT
|
|
cont_change += 5;
|
|
#endif
|
|
tmp = beformin->next;
|
|
beformin->next = tmp->next;
|
|
tmp->next = end->next;
|
|
end->next = tmp;
|
|
end = tmp;
|
|
#ifdef COUT_LIST
|
|
coutList(in);
|
|
#endif
|
|
}
|
|
}
|
|
void swap(int &a,int &b){
|
|
int tmp = a;
|
|
a = b;
|
|
b = tmp;
|
|
}
|
|
LinkNode* GetPartion(LinkNode* pBegin, LinkNode* pEnd)
|
|
{
|
|
int key = pBegin->data;
|
|
LinkNode* p = pBegin;
|
|
LinkNode* q = p->next;
|
|
|
|
while(q != pEnd)
|
|
{
|
|
#ifdef CONT
|
|
cont_change++;
|
|
cont_if++;
|
|
#endif
|
|
if(q->data < key)
|
|
{
|
|
#ifdef CONT
|
|
cont_change +=4;
|
|
#endif
|
|
p = p->next;
|
|
swap(p->data,q->data);
|
|
}
|
|
q = q->next;
|
|
}
|
|
#ifdef CONT
|
|
cont_change +=3;
|
|
#endif
|
|
swap(p->data,pBegin->data);
|
|
return p;
|
|
}
|
|
|
|
void QuickSort(LinkNode* pBeign, LinkNode* pEnd, LinkNode* in)
|
|
{
|
|
if(pBeign != pEnd)
|
|
{
|
|
LinkNode* partion = GetPartion(pBeign,pEnd);
|
|
#ifdef COUT_LIST
|
|
coutList(in);
|
|
#endif
|
|
QuickSort(pBeign,partion,in);
|
|
QuickSort(partion->next,pEnd,in);
|
|
}
|
|
}
|
|
void QuickSort(LinkNode* in){
|
|
#ifdef CONT
|
|
cont_if = 0;
|
|
cont_change = 0;
|
|
#endif
|
|
QuickSort(in, nullptr,in);
|
|
}
|
|
void freeTheLinkList(LinkNode* in){
|
|
while(in){
|
|
LinkNode* tmp = in;
|
|
in = tmp->next;
|
|
delete tmp;
|
|
}
|
|
}
|
|
void checkTheLinkList(LinkNode* in){
|
|
int tmp = in->next->data;
|
|
in = in->next;
|
|
while (in){
|
|
if(in->data<tmp){
|
|
cout << "error: 链表不是升序";
|
|
return;
|
|
}
|
|
in = in->next;
|
|
}
|
|
cout << "success: 连表是升序排列."<<endl;
|
|
}
|
|
int main() {
|
|
int size = 10;
|
|
char *sortType[] = {"插入排序", "冒泡排序", "快速排序", "选择排序"};
|
|
void (*sortFun[])(LinkNode *) = {InsertSort, BubbleSort, QuickSort, SelectionSort};
|
|
char *testType[] = {"随机数据", "顺序数据", "逆序数据"};
|
|
LinkNode *(*testFun[])(int) = {initArandList, initReList, initLinkList};
|
|
#ifndef COUT_LIST
|
|
size = 10;
|
|
for (int n = 1; n < 4; n++) {
|
|
size = size * 10;
|
|
cout << endl << "当前测试用数据规模:" << size << endl;
|
|
#endif
|
|
for (int j = 0; j < 3; j++) {
|
|
cout << "当前测试用例:" << testType[j] << endl;
|
|
for (int i = 0; i < 4; i++) {
|
|
auto randomlist = testFun[j](size);
|
|
#ifdef COUT_LIST
|
|
coutList(randomlist);
|
|
#endif
|
|
#ifndef CONT
|
|
clock_t start, end;
|
|
start = clock();
|
|
#endif
|
|
sortFun[i](randomlist);
|
|
#ifndef CONT
|
|
end = clock();
|
|
cout << sortType[i] << "用时:" << (end - start) << "毫秒" << endl;
|
|
#endif
|
|
#ifdef COUT_LIST
|
|
coutList(randomlist);
|
|
#endif
|
|
#ifdef CONT
|
|
cout << sortType[i] << "使用赋值:" << cont_change << "次" << endl;
|
|
cout << sortType[i] << "使用判断:" << cont_if << "次" << endl;
|
|
#endif
|
|
checkTheLinkList(randomlist);
|
|
freeTheLinkList(randomlist);
|
|
}
|
|
}
|
|
#ifndef COUT_LIST
|
|
}
|
|
#endif
|
|
return 0;
|
|
} |