直接插入法排序,vector数组实现(有关vector数组越界问题处理)

直接插入法排序,vector数组实现(以及"vector subscript out of range"越界问题处理)

直接插入法基本原理

在从小到大的排序过程中,设置一个哨兵位,如果a[ i ] > a[ i - 1 ](i 从 1 开始计数)则由哨兵位存储a[ i ]的value,此时哨兵大于a[ i - 1 ],从a[ i - 1 ]开始向前依次取a中各个元素与哨兵位比较大小,小于哨兵位的value值,则将其位置向后挪动一位,a[ i ]的值被替换为a[ i - 1]的值,以此类推…直到哨兵位不大于某个第 j 个元素时,因为此时原 j + 1的位置的值已经赋给了 j + 2位置,所以将哨兵位的value值赋值给 j + 1的位置即可
(特殊情况是:哨兵位比任意一个前面元素都小,即在与a[ 0 ]的value值比较后发现哨兵位比它还小,此时a[ 0 ]依旧按照前面的规则向后赋值给 a[1] ,哨兵位赋值给a[ 0 ],警惕此时不要再与a[-1]作比较,由于不存在a[-1]会造成数组越界的情况导致调试中断

代码段

/*直接插入排序,从左到右自小而大排序,
1) 设置哨兵,A[0]~A[n-1]存放原始数据
2) A[0]~A[L-1]有序,如果A[L]<A[L-1],哨兵存储A[L]的值
3) 从A[L-1]到A[0]依次与哨兵作比较,大于哨兵的往后移动
4) 用哨兵对移动之后空出来的位置进行赋值(也就是原A[L]的值)
5) 完成排序

输入样例:38 45 26 15 77 99 6 9 78 12

输出样例:6 9 12 15 26 38 45 77 78 99*/
#include<bits\stdc++.h>
using namespace std;
void InsertSort(vector<int> data)//直接插入排序函数
{
	int shaobing;	//哨兵位
	int j = 0;
	for (int i = 1; i < data.size(); i++)
	{//i 从 1 开始计数
		shaobing = 0;//每次循环哨兵位清零
		if (data[i] < data[i - 1])
		{
			shaobing = data[i];
			j = i - 1;
			if (j >= 0 && j < data.size())
			{
				for (j;  j >= 0 && j < data.size(); j--)//防止数组越界
				{
					if(shaobing < data[j])
                    {
					  data[j + 1] = data[j]; 
					}
					else 
					{
						break;
					}
				}
				/*
                 之前写的是:
          for(j; shaobing < data[j] && j >= 0 && j < data.size();j--)
               {
                 data[j+1] = data[j]; 
               }
             //后面都一样
    但是在执行过程中报错“vector subscript out of range”,造成调试中断 
    然后进行单步调试,打开 Watch监视器
    同时去看 i、j 、data[i] 、data[j] 、data[0]到data[9](因为自己设置的测试
    样例是十位数字)
    在单步调试的过程中,发现问题出在,j--的操作执行过后,j可能出现的最小值应该
    为-1,我们原本的愿望是j出现-1之后,代表哨兵位已经小于第一位数组元素,并且
    已经将原第一位元素的值赋给第二位的位置了,此时应该跳出循环,并在跳出去以后
    将哨兵的值赋给第一位元素,即赋值给a[j + 1];
    但是在我们希望利用j小于零的条件跳出循环的时候,循环中的判断部分还有一句同
    时执行的“shaobing < data[j]”语句,即判断是否要发生向后赋值的语句,也会进
    行判断,则在j=-1的情况下发生数组越界,造成中断,报错为"vector subscript
     out of range"
    处理办法:将“shaobing < data[j]”语句拿下来在循环体中以if else语句配合
    break跳出命令的格式实现其原功能。这样在循环判断过程中就不再会出现越界的情
    况
                 */
				if ((j+1) >= 0 && (j+1) < data.size())
				{
					data[j + 1] = shaobing;
				}
			}
		}
	}
	for (int i = 0; i < data.size(); i++)
	{
		cout << data[i] << ' ';
	}
}
int main() 
{
	vector <int> data;
	int data_in;
	while (1) 
	{
		cin >> data_in;
		data.push_back(data_in);//依次输入
		if (cin.get() == '\n') //带走回车
		{
			break;
		}
	}
	//验证输入的正确性
	/*for (int i = 0; i < data.size(); i++) 
	{
		cout << data[i]<<' ';
	}*/
	InsertSort(data);
}

测试样例的执行结果

posted @ 2023-12-21 09:48  在天边偷看小天使  阅读(92)  评论(0)    收藏  举报  来源