数组和链表的归并排序算法实现(C语言)
归并排序
二路归并
描述
时间复杂度是,空间复制度为(归并排序的最大缺陷)
归并排序(Merge Sort)完全遵循上述分治法三个步骤:
1、分解:将要排序的n个元素的序列分解成两个具有n/2个元素的子序列;
2、解决:使用归并排序分别递归地排序两个子序列;
3、合并:合并两个已排序的子序列,,产生原问题的解。
数组代码实现
print_arr(int *arr, int len)
{
int i = 0;
for(i = 0; i < len; i ++)
printf("%d ",arr[i]);
printf("\n");
}
void merge(int *arr, int low, int mid, int hight, int *tmp)
{
assert(arr && low >= 0 && low <= mid && mid <= hight);
int i = low;
int j = mid + 1;
int index = 0;
while(i <= mid && j <= hight)
{
if(arr[i] <= arr[j])
tmp[index++] = arr[i++];
else
tmp[index++] = arr[j++];
}
while(i <= mid)
tmp[index++] = arr[i++];
while(j <= hight)
tmp[index++] = arr[j++];
memcpy((void *)(arr + low), (void *)tmp, (hight - low + 1) * sizeof(int));
}
void mergesort(int *arr, int low, int hight, int *tmp)
{
assert(arr && low >= 0);
int mid;
if(low < hight)
{
mid = (hight + low) >> 1;
mergesort(arr, low, mid,tmp);
mergesort(arr, mid + 1, hight,tmp);
merge(arr, low, mid, hight,tmp);
}
}
//只分配一次内存,避免内存操作开销
void mergesort_drive(int *arr, int len)
{
int *tmp = (int *)malloc(len * sizeof(int));
if(!tmp)
{
printf("out of memory\n");
exit(0);
}
mergesort(arr, 0, len - 1, tmp);
free(tmp);
}
int main()
{
int data[10]={8,7,2,6,9,10,3,4,5,1};
int len = sizeof(data)/sizeof(data[0]);
mergesort_drive(data, len);
print_arr(data,len);
return 0;
}
链表代码实现
/*
当我们需要对链表进行排序时,由于不能对它的元素进行随机访问,
所以更适合使用归并排序,大名鼎鼎的快速排序用到链表上,效率也很低,
原因还是在于不能对链表中的元素进行随机访问,同理,采用堆排序更是不可能的事情。
*/
stdlibtime.h>
typedef int Item;
typedef struct Node
{
Item data;
struct Node *next;
}Node,*ptrNode;
ptrNode CreatListHead(int len);
ptrNode CreatListTail(int len);
void print_List(ptrNode List);
void Mergesort_List(ptrNode *List);
void Split_List(ptrNode List, ptrNode *List_A, ptrNode *List_B);
ptrNode Merge_List(ptrNode List_A, ptrNode List_B);
ptrNode CreatListHead(int len)
{
int i;
ptrNode p;
ptrNode List = (ptrNode)malloc(sizeof(struct Node));
;
for(i = 0; i < len; i ++)
{
p = (ptrNode)malloc(sizeof(struct Node));
pi + 1;
pnext;
List->next = p;
}
return List;
}
ptrNode CreatListTail(int len)
{
int i;
ptrNode p;
srand(time(0));
ptrNode List = (ptrNode)malloc(sizeof(struct Node));
ptrNode Tail = List;
for(i = 0; i < len; i ++)
{
p = (ptrNode)malloc(sizeof(struct Node));
prand() % len + 1;
Tail->next = p;
Tail = p;
}
Tail->next = NULL;
return List;
}
void print_List(ptrNode List)
{
)
{
printf();
next;
}
printf("\n");
}
void Mergesort_List(ptrNode *List)
{
ptrNode Head ;
ptrNode List_A;
ptrNode List_B;
Head->next == NULL)
return;
Split_List(Head, &List_A, &List_B);
Mergesort_List(&List_A);
Mergesort_List(&List_B);
Merge_List(List_A,List_B);
}
void Split_List(ptrNode List, ptrNode *List_A, ptrNode *List_B)
{
ptrNode fast_list;
ptrNode low_list;
next == NULL)
{
*List_A = List;
*List_B = NULL;
}
else
{
low_list = List;
fast_list next;
while(fast_list != NULL)
{
fast_list = fast_list->next;
if(fast_list != NULL)
{
low_list = low_list->next;
fast_list = fast_list->next;
}
}
*List_A = List;
*List_B = low_list->next;
low_list->next = NULL;
}
}
ptrNode Merge_List(ptrNode List_A, ptrNode List_B)
{
ptrNode List_Result = NULL;
if(List_A == NULL)
return List_B;
if(List_B == NULL)
return List_A;
List_B->data)
{
List_Result = List_A;
List_A = List_A->next;
}
else
{
List_Result = List_B;
List_B = List_B->next;
}
List_Result->next = Merge_List(List_A,List_B);
return List_Result;
}
int main()
{
ptrNode Head;
ptrNode List;
Head = CreatListTail(10);
List = Head ->next;
print_List(List);
Mergesort_List(&List);
print_List(List);
return 0;
}
适用场景