链表的归并排序,插入排序

来自数据结构与算法书
进行链表排序并避免创建,删除新的节点
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;
                }



            }
        }
    }

}``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值