在基础薄弱的时候即便是写一些简单的题也受益良多。
这是《算法导论》第二章第一节所举的全书第一个例子。
为了跟上时代的步伐以及让代码看起来更C++些,以后我会用cin、cout替代printf、scanf,用STL抽象容器替代数组、链表,用迭代器替代指针等。
但同时出于练基本功的考虑,尽量先不直接使用算法库提供的高级操作。
第一份代码是我凭印象自己实现的,定义了两个list,操作起来比较直观方便。
第二份是对照着书中提供的伪码实现的,只用了一个list,当然由于i最好不要超越begin(),对i到达first的情况作了单独处理。
因为找不到那种online judge system对代码作测试,所以无法保证不存在漏洞,个人测试结果暂时是都通过了,期间收获都总结在注释中。
insertion_sort_1.cpp
/*
2013.8.3
1,输入任意长度的整形数列
2,用普通插入法排序
3,输出结果
*/
#include <iostream>
#include <list>
using namespace std;
void insertion_sort( list<int> &A,list<int> &B)
{
list<int>::iterator iter_A = A.begin();
list<int>::iterator iter_B = B.begin();
B.insert(iter_B,*iter_A);
++iter_A;
A.pop_front();
while (iter_A != A.end())
{
for (iter_B = B.begin(); iter_B != B.end(); ++iter_B)
{
if ((*iter_A) < (*iter_B))
{
B.insert(iter_B,*iter_A);
++iter_A;
A.pop_front();
break;
}
}
if (iter_B == B.end())
{
B.push_back(*iter_A);
++iter_A;
A.pop_front();
}
}
}
int main()
{
list<int> list_A;
list<int> list_B;
int num;
while (cin >> num)
list_A.push_back(num);
if (list_A.empty())
{
cout<<"the array is empty";
return 0;
}
insertion_sort( list_A, list_B);
cout<<"the sorted array is:";
for (list<int>::iterator iter = list_B.begin(); iter != list_B.end(); ++iter)
cout<<(*iter)<<" ";
}
/*
一般知识点:
1,>> 会过滤掉掉不可见字符如空格、回车、TAB等,所以输入数字时这些键都起间隔作用。
2,使用istream对象作测试条件,结果是测试流的状态。输入有效则成功,遇到文件结束符或无效输入则失败。
3,将容器作为函数参数,一般通过迭代器传递。
4,要支持插入操作,明显应选用list容器。
5,注意向函数中传递容器时,要按引用传递。
6,函数形参最好不要与外部定义的实参取同名。
坑点:
1,erase、pop_front、pop_back使指向被删元素的迭代器失效,所以一定要先移动迭代器,再删除元素。
*/
insertion_sort_2.cpp
/*
2013.8.3
1,输入任意长度的整形数列
2,用普通插入法排序
3,输出结果
4,采用《算法导论》给出的伪代码思路
*/
#include <iostream>
#include <list>
using namespace std;
void insertion_sort( list<int> &A)
{
int key;
int temp;
for( list<int>::iterator iter = ++A.begin(); iter != A.end(); ++iter)
{
key = *iter;
list<int>::iterator i;
i = --iter;
iter++;
while((i != A.begin())&&((*i) > key))
{
temp = *i;
*(++i) = temp;
--i;
--i;
}
if( i == A.begin())
{
if( *i > key)
{
temp = *i;
*(++i) = temp;
--i;
*i = key;
}
else
*(++i) = key;
}
else
*(++i) = key;
}
}
int main()
{
list<int> list_A;
int num;
while( cin >> num)
A.push_back(num);
if( list_A.empty())
{
cout<<"the array is empty";
return 0;
}
insertion_sort( list_A);
cout<<"the sorted array is:";
for( list<int>::iterator iter = list_A.begin(); iter != list_A.end(); ++iter)
cout<<(*iter)<<" ";
}
/*
一般知识点:
1,list容器的iter仅支持iter++等,不支持iter+n,即便n = 1也不行。
坑点:
1,自增运算++放在前面返回修改后的值,而放在后面返回原来的值。比如*(++i) = key;等同于i++; *i = key; 而*(i++) = key等同于*i = key; i++;如此则出错。
养成只在必要时使用后置操作符的习惯,因为++i性能更优且适用于大多数情况。
*/