//Filename: List.h #ifndef LIST_H_INCLUDED #define LIST_H_INCLUDED template<class T> struct Node{ T value; Node<T> *link; Node(Node<T> *l =NULL){ link = l; } Node(const T &x, Node<T> *l=NULL){ value = x; link = l; } }; //List类及所需函数定义 template<class T> class List{ public: List(){first =new Node<T>;}; ~List(){ //cout<<"析构ing"<<endl; makeEmpty(); }; void copy(List<T> &L) //拷贝链表,全拷贝 { makeEmpty(); T value; Node<T> *current = first; Node<T> *currentofL = L.first; while(currentofL->link!= NULL) { value = currentofL->link->value; current->link = new Node<T>(value); currentofL = currentofL->link; current = current->link; } current->link = NULL; } void makeEmpty() //清空链表 { Node<T> *current = first; while(current->link!=NULL) { Node<T> *temp = current->link; current->link = temp->link; delete temp; } } int GetLength()//得到链表的长度 { int count = 0; Node<T> *current = first->link; while(current!=NULL) { count++; current = current->link; } return count; } Node<T> *GetNode(int n) //返回第n个节点,n从一开始计数 { Node<T> *current = first; if(n<=0) { cerr<<"所查找节点值太小!"<<endl; return NULL; } for(int i =0;i<n;i++) { current= current->link; if(current ==NULL) { cout<<"所查找节点超出链表总长度!"<<endl; return NULL; } } return current; } Node<T> *GetTail()//找到链表尾部 { Node<T> *current = first; while(current->link!=NULL) current = current->link; return current; } void RemoveTail() //去掉最后一个节点 { Node<T> *pre = NULL ; Node<T> *current = first; if(current->link==NULL) { cerr<<"There is no item in the list"<<endl; return; } while(current->link != NULL)//current->link若为NULL,则current为尾部 { pre = current; current = current->link; } delete current; pre->link = NULL; } void AddToTail(const T &x)//链表尾部添加 { Node<T> *newNode = new Node<T>(x); Node<T> *tail = GetTail(); tail->link = newNode; } void InsertbySort(const T &x)//按顺序插入,在按顺序重构链表用到 { Node<T> *current = first; Node<T> *newNode = new Node<T>(x); while(current->link != NULL) { if(x > current->link->value) current = current->link; else { newNode->link = current->link; current->link = newNode; return; } } //插入到了尾部 current->link =newNode; newNode->link = NULL; } void ReConstructSort() //构造新的链表形成排序,此方法空间要求较大 { int length = GetLength(); List<T> newList; for(int i =1;i<=length;i++) { Node<T> *tempNode = GetNode(i); T temp = tempNode->value; newList.InsertbySort(temp); } copy(newList); //注意是全拷贝 } void SelectSort()//选择排序,每次选择未排序部分的最小值交换到前面 { if(first->link == NULL) return; //链表为空 if(first->link->link ==NULL) return; //只有一个节点 Node<T> *pSorting = first->link; //记录正在排序的点 while(pSorting!=NULL) { Node<T> *pTemp = pSorting->link; //从pSorting开始往后遍历 Node<T> *pMin = pSorting; //暂存从pSorting开始的最小的点 while(pTemp!=NULL) { if(pTemp->value < pMin->value) pMin = pTemp; pTemp = pTemp->link; } //进行交换 T temp = pSorting->value; pSorting->value = pMin->value; pMin->value = temp; //排序下一个点 pSorting = pSorting->link; } } void InsertSort()//插入排序 { if(first->link == NULL) return; //链表为空 if(first->link->link ==NULL) return; //只有一个节点,返回 Node<T> *pInsert = first->link->link; //插入的点 Node<T> *pSorting = first->link; //前面到pSorting已经有序,则pSoring->link是下一个需要排序的点 while(pInsert != NULL) { Node<T> *pTemp = first->link; Node<T> *pPre = first; while(pTemp!=pInsert && pTemp->value <= pInsert->value) { pTemp = pTemp->link; pPre = pPre->link; } if(pTemp == pInsert) //所插入的值比前面的都大,则无需调整 pSorting= pInsert; else { pSorting->link = pInsert->link; //pSorted->link将是下一个需要排序的点 pPre->link = pInsert; pInsert->link = pTemp; } pInsert = pSorting->link; } } void BubbleSort()//冒泡排序,每次将最大的交换到后面 { if(first->link == NULL) return; //链表为空 if(first->link->link ==NULL) return; //只有一个节点,返回 bool isChange = true; Node<T> *pStop = NULL; while(isChange && pStop!= first->link) { isChange = false; Node<T> *pTemp = first->link; while(pTemp->link!= pStop) { if(pTemp->value > pTemp->link->value) { swap(pTemp->value,pTemp->link->value); isChange = true; } pTemp = pTemp->link; } pStop = pTemp; } } void QuickSort() //快速排序 { if(first->link == NULL) return; if(first->link->link ==NULL) return ; qSort(first->link,NULL); } void qSort(Node<T> *left, Node<T> *right) //快速排序递归 { //排序范围为[left,right) //注意左闭右开,即右边界并不参与排序 if(left != right && left->link!=right) { Node<T> *mid = partition(left,right); qSort(left,mid); qSort(mid->link,right); } } Node<T>* partition(Node<T> *left, Node<T> *right) //快排左右分割 { //直接选择left作为分割点 T key = left->value; Node<T> *loc = left; for(Node<T> *i = left->link;i!=right;i = i->link) { if(i->value < key) //每次遇到比key小的就交换到前面,loc->link就是要交换到的位置 { loc = loc->link; swap(loc->value,i->value); } } swap(loc->value,left->value); //将临界值换到中间 return loc; } private: Node<T> *first; //头结点,并不存数值 }; #endif // LIST_H_INCLUDED
//Filename:TestOfSort.cpp #include <iostream> #include <time.h> #include "List.h" using namespace std; //链表排序功能演示 void TestOfSort() { cout<<"----Test Of Sort----"<<endl; List<int> l; //srand((unsigned)time(0));//初始化随机数种子 char c = 'n'; while(c=='n') { l.makeEmpty(); for(int i = 0;i<10;i++) //链表添加20个随机数 { int temp = rand()%100; l.AddToTail(temp); //每次都加入到尾部 } cout<<"\nBefore Sorting."<<endl; for(int i = 1;i<=l.GetLength();i++) { cout<<l.GetNode(i)->value<<" "; } cout<<"\n选择排序方式(1.选择排序;2.插入排序;3.重构排序;4.冒泡排序;5.快速排序):"; int choose; cin>>choose; switch(choose) { case 1: l.SelectSort();break; case 2: l.InsertSort();break; case 3: l.ReConstructSort();break; case 4: l.BubbleSort();break; case 5: l.QuickSort();break; default: l.SelectSort();break; } cout<<"After Sorting."<<endl; for(int i = 1;i<=l.GetLength();i++) { cout<<l.GetNode(i)->value<<" "; } cout<<endl; cout<<"是否退出(y or n):"; cin>>c; } };
//Filename: main.cpp #include <iostream> #include <time.h> #include "List.h" using namespace std; void TestOfSort(); int main() { TestOfSort(); system("pause"); return 0; }