普通插入排序

在基础薄弱的时候即便是写一些简单的题也受益良多。


这是《算法导论》第二章第一节所举的全书第一个例子。


为了跟上时代的步伐以及让代码看起来更C++些,以后我会用cincout替代printfscanf,用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性能更优且适用于大多数情况。
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值