来自数据结构与算法书
进行链表排序并避免创建,删除新的节点
1.Node是结构体模板,LinkList是类模板
using namespace std;
template <class Node_entry>
struct Node
{
Node_entry entry;
Node *next;
Node();
Node(Node_entry item, Node *add_on=NULL);
};
template <class Record>
class LinkList
{
public:
LinkList();
~LinkList();
int create_linklist(int n);
void print();
void merge_sort();
void recursive_merge_sort(Node<Record> * & sub_list);
Node<Record> * divide(Node<Record>* sub_list);
Node<Record>* merge(Node<Record>* first,Node<Record>* secord);
int add_from_tail(Record item);
int length();
private:
Node<Record>* Head;
Node<Record>* Tail;
int count;
};
2 归并排序
template <class Record>
void LinkList<Record>::merge_sort()
{
recursive_merge_sort(Head);
Node<Record>*p=Head;
while(p->next!=NULL)
{
p=p->next;
}
Tail=p;
}
//merge_sort的意义在于可以把私有成员head传给recursive_merge_sort作为参数
//recursive_merge_sort的参数是一个指针的引用,可以改变指针的指向。
//我们需要改变head的指向,但不可以在main中用gethead()作为参数,它return head后返回值是个临时变量,不能对它取引用,因为函数完成后栈中数据就会销毁。
//tail的指向要额外改
//若把gethead()返回值赋给另一个指针变量,然后把它作为参数传给recursive_merge_sort()也没有用,因为改变的只是另一个指针变量的指向,不是head的指向。
template <class Record>
void LinkList<Record>::recursive_merge_sort(Node<Record> * & sub_list)
{
if(sub_list!=NULL&&sub_list->next!=NULL)
{
Node<Record>* second=divide(sub_list);
recursive_merge_sort(sub_list);
recursive_merge_sort(second);
sub_list=merge(sub_list,second);
}
}
template <class Record>
Node<Record> * LinkList<Record>::divide(Node<Record>* sub_list)
{
Node<Record>* position,* midpoint,* second;//midpoint 遍历链表的速度是position的一半,把链表分成两份。最后second是第二个链表的头结点,midpoint是第一个链表最后一个节点
midpoint=sub_list;
if(midpoint==NULL) return NULL;
position=midpoint->next;
while(position!=NULL)
{
position=position->next;
if(position!=NULL)
{
midpoint=midpoint->next;
position=position->next;
}
}
second=midpoint->next;
midpoint->next=NULL;//用NULL代替中间链,把链表分成两份
return second;
}
template <class Record>
Node<Record>* LinkList<Record>::merge(Node<Record>* first,Node<Record>* second)
{
Node<Record> combined;//为记录归并表而不考虑头结点特殊情况,将combined作为一个哑结点,将它放在归并表的起始处,它的next是归并表实际起始节点。
Node<Record>*last_sorted;//指向排好的最后一个节点
last_sorted=&combined;
while(first!=NULL && second!=NULL)
{
if(first->entry<second->entry)
{
last_sorted->next=first;
last_sorted=first;
first=first->next;
}
else
{
last_sorted->next=second;
last_sorted=second;
second=second->next;
}
}
if(first!=NULL)//不同于数组的归并排序,只要把一个节点链上去所有的就链上去了
{
last_sorted->next=first;
}
else
{
last_sorted->next=second;
}
return combined.next;
}
如果不用哑结点,要考虑头结点的特殊情况。返回值是指向new出来的空间的指针,所以不会出错。
template <class Record>
Node<Record>* LinkList<Record>::merge(Node<Record>* first,Node<Record>* second)
{
Node<Record>* combined;
Node<Record>*last_sorted;
last_sorted=combined;
combined=NULL;
while(first!=NULL && second!=NULL)
{
if(first->entry<second->entry)
{
if(combined==NULL)
{
last_sorted=combined=first;
first=first->next;
}
else
{
last_sorted->next=first;
last_sorted=first;
first=first->next;
}
}
else
{
if(combined==NULL)
{
last_sorted=combined=second;
second=second->next;
}
else
{
last_sorted->next=second;
last_sorted=second;
second=second->next;
}
}
}
if(first!=NULL)
{
last_sorted->next=first;
}
else
{
last_sorted->next=second;
}
return combined;
}
3 插入排序
template <class Record>
void LinkList<Record>::insert_sort()//insert element into the already sorted part(between head and lastsorted)
{
Node<Record> *last_sorted,*first_unsorted,* trailing,*current;
if(Head !=NULL)
{
last_sorted=Head;
while(last_sorted->next!=NULL)
{
first_unsorted=last_sorted->next;
if(first_unsorted->entry<Head->entry)//insert before the head
{
last_sorted->next=first_unsorted->next;
first_unsorted->next=Head;
Head=first_unsorted;
}
else
{
trailing=Head;
current=Head->next;
while(first_unsorted->entry>current->entry)//the node after the sorted part is first_unsorted itself,so the loop will terminate at last
{
trailing=current;
current=current->next;
}
if(current==first_unsorted)//insert after lastsorted
{
last_sorted=first_unsorted;
}
else//insert behond head and before lastsorted
{
trailing->next=first_unsorted;
last_sorted->next=first_unsorted->next;
first_unsorted->next=current;
}
}
}
}
}``