//----------------------------------------------------------------
//----------------------------------------------------------------
/*
A Practical Introduction to Data Structures and Algorithm Analysis, Second Edition
第7章7.2 7.10 7.18的参考程序,及较为详尽的注释。
和书上一样的类或函数(例如:Comp、swap、qsort)没有包括在里面,如有需要,请自行添加。
由于作者水平有限,难免存在错漏之处,恳请读者批评指正。
本文仅供学习交流之用,请勿用于其他用途。转载请先和作者联系。
Copyright(c) 2006 byWinark. All rights reserved.
*/
//----------------------------------------------------------------
//----------------------------------------------------------------
//7.2
#include<iostream>
#include<stack>//C++标准模板库(STL)中的stack(栈)
#include"../DataStructures/sort.h"//提供Comp的头文件,如有需要,请自行添加。
usingnamespace std;
//基于栈的插入排序
template<classElem, class Comp>
stack<Elem>insertsort(stack<Elem> &s1)
{
Elem val;
int count;
stack<Elem> s2;//存放已排序元素的栈,栈顶元素小于栈底元素
while(!s1.empty())
{
val=s1.top();//从s1弹出一个元素放入val
s1.pop();
count=0;
while(!s2.empty() &&Comp::lt(s2.top(),val))//如果s2顶部的元素比val小,则将s2顶部的元素弹出并压入s1,直到s2顶部的元素大于等于val,或s2空为止
{
s1.push(s2.top());
s2.pop();
count++;
}
s2.push(val);//将val压入s2
while (count>0)
{
s2.push(s1.top());
s1.pop();
count--;
}
}
return s2;
}
voidmain()
{
const int n=9;//元素个数
int a[n]={1,9,3,5,7,8,2,6,4};
stack<int> s1, s2;//C++标准模板库(STL)中的stack(栈)
int i;
for (i=0; i<n; i++)//将元素压入s1
{
s1.push(a[i]);
cout<<s1.top()<<ends;
}
cout<<endl;
s2=insertsort<int,Comp>(s1);
while(!s2.empty())//弹出并输出s2中的所有元素
{
cout<<s2.top()<<ends;
s2.pop();
}
cout<<endl;
getchar();
}
//----------------------------------------------------------------
//----------------------------------------------------------------
//7.10
#include<iostream>
#include<string.h>//使用strcmp需要的头文件
#include<stdio.h>//使用gets和puts需要的头文件
#include"../DataStructures/sort.h"//提供qsort的头文件,如有需要,请自行添加。
usingnamespace std;
//比较字符指针的指针(char **)的类
classCharPointerComp
{
public:
template<class Elem>
static bool lt(Elem x,Elem y){returnstrcmp(*x, *y)<0;}//字符指针x指向的字符串小于字符指针y指向的字符串
template<class Elem>
static bool eq(Elem x,Elem y){returnstrcmp(*x, *y)==0;}//字符指针x指向的字符串等于字符指针y指向的字符串
template<class Elem>
static bool gt(Elem x,Elem y){returnstrcmp(*x, *y)>0;}//字符指针x指向的字符串大于字符指针y指向的字符串
};
voidmain()
{
const int n=9;//元素个数
int i;
char *cstr[n];//字符串数组
char **csp[n];//字符串指针数组
for (i=0; i<n; i++)//从键盘读入n行字符,放入字符串数组cstr,并将字符串数组cstr中每个元素的地址赋值给字符串指针数组csp中对应下标的元素
{
cstr[i]=newchar[256];//申请空间
gets(cstr[i]);//从键盘读入一行字符
csp[i]=&cstr[i];//将字符串数组cstr中每个元素的地址赋值给字符串指针数组csp中对应下标的元素
}
cout<<endl;
qsort<char**, CharPointerComp>(csp, 0, n-1);//调用书上的快速排序
for (i=0; i<n; i++)//按顺序输出字符串指针数组csp中每个元素所指向的字符串
puts(*csp[i]);
getchar();
}
//----------------------------------------------------------------
//----------------------------------------------------------------
//7.18
#include<iostream>
#include<list>//C++标准模板库(STL)中的list(双向链表)
#include"../DataStructures/sort.h"//提供Comp的头文件,如有需要,请自行添加。
usingnamespace std;
//基于list的归并排序
template<classElem, class Comp>
list<Elem>mergeSort(list<Elem>l1)
{
int size=(int)l1.size();
if (size<2)//如果list里面小于两个元素,不需排序,直接返回。
return l1;
int i, half=size/2;
list<Elem> l2, l3;
for (i=0; i<half; i++)//参考书上Mergesort的优化版本,将l1后半部分倒过来放入l2
{
l2.push_back(l1.back());
l1.pop_back();
}
l1=mergeSort<Elem,Comp>(l1);//将左半部分的list排序
l2=mergeSort<Elem,Comp>(l2);//将右半部分的list排序
for (i=0; i<size; i++)//将l1、l2按顺序合并成l3,和书上的Mergesort类似
{
if (l1.empty())//如果l1为空,将l2的元素放入l3
{
l3.push_back(l2.front());
l2.pop_front();
}else
if (l2.empty())//如果l2为空,将l1的元素放入l3
{
l3.push_back(l1.front());
l1.pop_front();
}else//将l1、l2的第一个元素中较小的那个放入l3
if (Comp::lt(l1.front(),l2.front()))//l1的第一个元素比l2的小,将l1的第一个元素放入l3
{
l3.push_back(l1.front());
l1.pop_front();
}else//l2的第一个元素比l1的小或相等,将l2的第一个元素放入l3
{
l3.push_back(l2.front());
l2.pop_front();
}
}
return l3;//返回由l1、l2合并排序生成的l3
}
voidmain()
{
const int n=9;//元素个数
int a[n]={1,9,3,5,7,8,2,6,4};
int i;
list<int> l1, l2;//C++标准模板库(STL)中的list(双向链表)
list<int>::iteratoriter;//list的迭代子,用来访问list中的节点
for (i=0; i<n; i++)//将元素插入l1
{
l1.push_back(a[i]);
cout<<l1.back()<<ends;
}
cout<<endl;
l2=mergeSort<int,Comp>(l1);
for (iter=l2.begin();iter!=l2.end();iter++)//遍历l2的节点,并输出每个节点的值
{
cout<<*iter<<ends;//*是重载了的用于获得迭代子所指向的节点值的函数
}
cout<<endl;
getchar();
}
//----------------------------------------------------------------
//----------------------------------------------------------------