我正在使用C ++为自己的链表类编写自己的合并排序函数。我测试了我的Split_List和Merge函数,它们运行良好。但是我遇到了Merge_Sort递归函数的问题:它可以合并排序链表的左右部分,但最终合并整个链表时会出错。
输出:
第一份清单: [100] - > [2] - > [37] - > [ - 10] - > |||
排序第一个清单: [37] - > [100] - > |||
node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
template <typename T>
class node{
public:
node(const T& data){item=data; link=NULL;}
int item;
node* link;
};
#endif // NODE_H
linked_list.h
#ifndef Linked_List_H
#define Linked_List_H
#include "node.h"
#include <iostream>
using namespace std;
template<typename T>
class Linked_List{
public:
Linked_List(){tail=head=NULL; count=0;}
void Insert_Head(const T& item);
void Append_Tail(const T& item);
void Insertion_Sort();
void Merge_Sort();
void Print();
int Size() {return count;}
private:
node<T>* head;
node<T>* tail;
int count;
void InsertHead(node<T>* &list_head, const T& item);
void InsertBefore(node<T>* &list_head, node<T>* here, const T& item);
void Append_Tail(node<T>* &list_head, node<T>* end);
void Delete(node<T>* &list_head, node<T>* deleteHere);
node<T>* DeleteHead(node<T>* &list_head);
void Merge_Sort(node<T>* list_head, int size);
node<T>* Merge(node<T>* left, node<T>* right);
node<T>* Split_List(node<T>* list_head, int size);
void Print(node<T>* list_head);
};
template<typename T>
void Linked_List<T>::Merge_Sort(){
Merge_Sort(head, count);
}
template<typename T>
void Linked_List<T>::Merge_Sort(node<T>* list_head, int size){
int n1;
int n2;
node<T>* right_head;
if(size>1){
right_head=Split_List(list_head, size);
n1=size/2;
n2=size-n1;
Merge_Sort(list_head, n1);
Merge_Sort(right_head, n2);
head=Merge(list_head, right_head);
}
}
template<typename T>
node<T>* Linked_List<T>::Split_List(node<T>* list_head, int size){
if (size==0){
return NULL;
}else if (size==1){
return list_head;
}else{
node<T>* iter=list_head;
node<T>* right_head=NULL;
int i=0;
while (i<size/2-1){
iter=iter->link;
i++;
}
right_head=iter->link;
iter->link=NULL;
return right_head;
}
}
template<typename T>
node<T>* Linked_List<T>::Merge(node<T>* left, node<T>* right){
node<T>* newHead=NULL;
while (left!=NULL && right!=NULL){
if (left->item<=right->item){
Append_Tail(newHead, DeleteHead(left));
}else{
Append_Tail(newHead, DeleteHead(right));
}
}
if (left==NULL){
while (right!=NULL){
Append_Tail(newHead, DeleteHead(right));
}
}else{
while (left!=NULL){
Append_Tail(newHead, DeleteHead(left));
}
}
return newHead;
}
template<typename T>
void Linked_List<T>::Insertion_Sort(){
node<T>* end=head;
while (end!=NULL){
for (node<T>* iter=head; iter!=end; iter=iter->link){
if (iter->item>=end->item){
InsertBefore(head, iter, end->item);
Delete(head, end);
break;
}
}
end=end->link;
}
}
template<typename T>
void Linked_List<T>::Insert_Head(const T& item){
InsertHead(head, item);
}
template<typename T>
void Linked_List<T>::InsertHead(node<T>* &list_head, const T& item){
node<T>* tempPtr=new node<T> (item); //create new node
tempPtr->link=list_head; //connect the new node to orignal 1st node
list_head=tempPtr; //make the head point to the new node as the new 1st node
count++;
}
template <typename T>
void Linked_List<T>::InsertBefore(node<T>* &list_head, node<T>* here, const T& item){
if (list_head==NULL || list_head==here)
{
InsertHead(head, item); //add "head" node
return;
}else{
node<T>* tempPtr=new node<T>(item); //create new node
node<T>* previous=head;
while (previous->link!=here){
previous=previous->link; //if the previous node cannot be found, go to the link node
}
tempPtr->link=here; //if the previous node is found, connect the new node to "here" node
previous->link=tempPtr;
count++;
}
}
template<typename T>
void Linked_List<T>::Append_Tail(const T& item){
if (head==NULL)
{
InsertHead(head, item); //add "head" node
tail=head;
}else{
node<T>* tempPtr=new node<T>(item); //create new node
tail->link=tempPtr;
tail=tail->link;
count++;
}
}
template<typename T>
void Linked_List<T>::Append_Tail(node<T>* &list_head, node<T>* end){
if (list_head==NULL)
{
end->link=list_head; //connect the new node to orignal 1st node
list_head=end; //make the head point to the new node as the new 1st node
count++;
tail=list_head;
}else{
tail->link=end;
tail=tail->link;
count++;
}
}
template<typename T>
void Linked_List<T>::Delete(node<T>* &list_head, node<T>* deleteHere){
node<T>* here=list_head;
if (here==NULL)
{
cout<<"Empty linked list!"; //empty linked list
return;
}
else{
node<T>* previous=list_head;
if (deleteHere==list_head){
list_head=deleteHere->link; //if the deleted node is the 1st node, let the head point to the link node
count--;
}
else{
while (previous->link!=deleteHere){
previous=previous->link; //if the previous node cannot be found, go to the link node
}
previous->link=deleteHere->link;
//if the previous node is found, connect the previous node to the node after the deleted node
count--;
}
}
}
template<typename T>
node<T>* Linked_List<T>::DeleteHead(node<T>* &list_head){
node<T>* deleted=list_head;
list_head=list_head->link; //if the deleted node is the 1st node, let the head point to the link node
count--;
deleted->link=NULL;
return deleted;
}
template<typename T>
void Linked_List<T>::Print(){
Print(head);
}
template<typename T>
void Linked_List<T>::Print(node<T>* list_head){
node<T>* iter;
for (iter=list_head; iter!=NULL; iter=iter->link){
cout<<"["<<(iter->item)<<"]->";
}
cout<<"|||"<<endl<<endl;
}
#endif // Linked_List_H
的main.cpp
#include <iostream>
#include "linked_list.h"
using namespace std;
int main()
{
Linked_List<int> list1;
list1.Insert_Head(-10);
list1.Insert_Head(37);
list1.Insert_Head(2);
list1.Insert_Head(100);
cout<<"1st list: "<<endl;
list1.Print();
cout<<"sorted 1st list: "<<endl;
list1.Merge_Sort();
list1.Print();
}
答案 0 :(得分:1)
如果您在代码中添加了一些过多的Print
来电,您就会看到问题所在。您可以正确排序size-2列表,但在顶级列表中,在:
Merge_Sort(list_head, n1);
Merge_Sort(right_head, n2);
list_head
将成为列表[100]->|||
,right_head
将成为列表[37]->|||
。你实际上正在合并和排序,只是那些指针没有改变,所以你开始:
[100] -> [2] -> Nil
^
list_head
最后:
[2] -> [100] -> Nil
^
list_head
和其他名单一样。因此,只要您担心这一点,您只需合并两个大小为1的列表,这些列表就是您正确执行的 - 这就是您最终只使用37
和100
的方式。
这应该指向正确的方向。