归并排序
1.具有哨兵的归并排序
时间复杂度近似于lgn,因为分治管理看上去就像一棵二叉树。
void MERGE1(vector<int> &val, int begindex, int midindex, int len)//有哨兵
{
cout << "begindex: " << begindex << "\tendindex: " << midindex << "\tlen: " << len << endl;
//begindex : 0 endindex : 0 len : 1//拿出下标为0,1的元素比较并放入val数组的0,1中
//begindex : 0 endindex : 1 len : 2//比较0,1,2下标的元素合并
//begindex : 3 endindex : 3 len : 4//比较3,4下标的元素合并
//begindex : 0 endindex : 2 len : 4//比较0,1,2,3,4下标的元素合并
//begindex : 5 endindex : 5 len : 6//比较5,6
//begindex : 5 endindex : 6 len : 7//比较5,6,7
//begindex : 8 endindex : 8 len : 9//比较8,9
//begindex : 5 endindex : 7 len : 9//比较5,6,7,8,9
//begindex : 0 endindex : 4 len : 9//比较0,1,2,3,4,5,6,7,8,9,合并
vector<int> LVal, RVal;
int Lindex = midindex - begindex + 1;//表示左边的元素个数
int Rindex = len - midindex;//表示右边的元素个数
int i, j, k;
for (i = 0; i < Lindex; i++)
{
LVal.push_back(val[begindex + i]);//将从begindex下标开始存放元素
}
for ( j = 0; j < Rindex; j++)
{
RVal.push_back(val[midindex + j + 1]);//midindex + j + 1以这个下标为起始存放元素
}
LVal.push_back(1000);//定义哨兵//前提是要知道你的数据的最值,不然无法定义哨兵节点。
RVal.push_back(1000);//比如我数据的最值是100以内的元素,所以哨兵定义为1000是正确的
i = 0;
j = 0;
for (k = begindex; k <= len; k++)//k=begindex表示从第几个数组下标开始比较元素
{
if (LVal[i] <= RVal[j])
{
val[k] = LVal[i++];
}
else
{
val[k] = RVal[j++];
}
}
}
void MERGE_SORT(vector<int> &val, int begindex, int endindex)
{
if (begindex < endindex)
{
int mid = (begindex + endindex) / 2;
MERGE_SORT(val, begindex, mid);
MERGE_SORT(val, mid + 1, endindex);
MERGE1(val, begindex, mid, endindex);
}
}
2.无哨兵归并排序
void MERGE2(vector<int> &val, int begindex, int midindex, int len)//无哨兵
{
vector<int> Assist;
int Lindex = midindex - begindex + 1;//左序列
int Rindex = len - midindex;//右序列
int i, j;
i = begindex; j = midindex+1;//标记两个子序列应该从val数组中那个索引开始
while (0<Lindex && 0< Rindex)//循环对比数据,直至某个序列被全部放入Assist数组中
{
if (val[i] <= val[j])
{
Assist.push_back(val[i++]);
Lindex--;
}
else
{
Assist.push_back(val[j++]);
Rindex--;
}
}
while (Lindex > 0)//判断左子序列是否还存在元素
{
Assist.push_back(val[i++]);
Lindex--;
}
while (Rindex > 0)//判断右子序列是否还存在元素
{
Assist.push_back(val[j++]);
Rindex--;
}
i = 0;
for (size_t k = begindex; k <= len; k++)//val是从begindex索引开始排序的,所以k要初始化成开始排序的索引
{
val[k] = Assist[i++];
}
}
void MERGE_SORT(vector<int> &val, int begindex, int endindex)
{
if (begindex < endindex)
{
int mid = (begindex + endindex) / 2;
MERGE_SORT(val, begindex, mid);
MERGE_SORT(val, mid + 1, endindex);
MERGE2(val, begindex, mid, endindex);
}
}
主函数随便写写就行了
int main()
{
vector<int> val;
for (size_t i = 0; i < 10; i++)
{
int value = rand() % 100;
val.push_back(value);
}
for (size_t i = 0; i < 10; i++)
{
cout << val[i] << " ";
}
cout << endl;
MERGE_SORT(val, 0, 9);
for (size_t i = 0; i < 10; i++)
{
cout << val[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
归并排序用来处理大量数据排序性能是非常好的因为天然是二叉树的性质。