标题:单链表
只看楼主
GBH1
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:5
帖 子:112
专家分:510
注 册:2017-6-13
结帖率:100%
已结贴  问题点数:20 回复次数:5 
单链表
这个算法看了半天没看明白机制,谁能解释一下具体实现过程
例如数据:L,8,7,9,3,5,4,2
L为头结点,只有指针域,没有数据域
void Sort(LinkList &L){
    //本算法实现将单链表L的结点重排,使其递增有序
    LNode *p=L->next, *pre;
    LNode *r=p->next;  //r保持*p后继结点指针,以保证不断链
    p->next=NULL;  //构造只含一个数据结点的有序表
    p=r;
    while(p!=NULL){
        r=p->next;  //保存*p的后继结点指针
        pre=L;
        while (pre->next!=NULL && pre->next->data<p->data)
            pre=pre->next;  //在有序表中查找插入的前驱结点*pre
        p->next=pre->next;  //将*p 插入到*pre 之后
        pre->next=p;
        p=r; //扫描原单链表中剩下的结点
    }
}
搜索更多相关主题的帖子: 单链表 结点 指针 next NULL 
2017-08-06 19:32
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
这个嘛~试试画图~我自己曾经写过类似的仿照冒泡法排序~要说解释有动态图解会方便很多~
到底总觉得自己说了很多不中用的~或者说我可以理解但表达过来的感觉自己也不怎么会理解了~到底还是喜欢自己理解去~

PS:可以试试记录一趟排序的指针指向变动以及变动顺序~

[此贴子已经被作者于2017-8-6 20:10编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-08-06 20:08
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:5 
这个是不带头节点的~当然带头节点的可以简单一些~可以对比参照一下~

程序代码:
Node* sort(Node* head)
{
    Node tnode={0};
    Node* p=&tnode;
    tnode.next=head;

    while (p->next)
    {
        Node* pt=p;

        while (pt->next)
            if (pt->next->n<p->next->n)
            {
                Node* tmp=pt->next->next;
                pt->next->next=p->next;
                p->next=pt->next;
                pt->next=tmp;
            }
            else
                pt=pt->next;

        p=p->next;
        
    }
    return tnode.next;
}

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-08-06 20:15
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
这种排序感觉有点别致~好像不是冒泡法排序~更加像插入排序~和数组的插入排序区别是不用变动整个数据~值得学习~

哇~利用链表特有的性质~感觉比我二楼曾经写的仿照冒泡法排序效率要高一些~赶紧记录一下~

[此贴子已经被作者于2017-8-6 20:26编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-08-06 20:22
静水且流深
Rank: 5Rank: 5
等 级:贵宾
威 望:11
帖 子:60
专家分:319
注 册:2017-7-7
得分:15 
//这个算法看了半天没看明白机制,谁能解释一下具体实现过程
//例如数据:L,8,7,9,3,5,4,2
//L为头结点,只有指针域,没有数据域
程序代码:
#include<stdio.h>
#include<malloc.h>
typedef struct LNode{
    int data;
    struct LNode *next;
}LNode;
typedef LNode *LinkList;
void Show(LinkList &L) {
    LNode *p=L->next;
    while(p!=NULL){
        printf("%d,", p->data);
        p=p->next;
    }
    printf("\n");
}
void Sort(LinkList &L){
    //本算法实现将单链表L的结点重排,使其递增有序
    LNode *p=L->next, *pre;
    LNode *r=p->next;  //r保持*p后继结点指针,以保证不断链
    p->next=NULL;  //构造只含一个数据结点的有序表
    p=r;
    while(p!=NULL){
        r=p->next;  //保存*p的后继结点指针
        pre=L;
        while (pre->next!=NULL && pre->next->data<p->data)
            pre=pre->next;  //在有序表中查找插入的前驱结点*pre
        p->next=pre->next;  //将*p 插入到*pre 之后
        pre->next=p;
        p=r; //扫描原单链表中剩下的结点
           Show(L);
    }
}

main(){
    LinkList h = (LinkList)malloc(sizeof(LNode));
    LNode *p=h;
    int a[]={8,7,9,3,5,4,2};
    for(int i=0;i<7;i++){
        LNode *q = (LNode*)malloc(sizeof(LNode));
        q->data=a[i];
        q->next=NULL;
        p->next=q;
        p=q;
    }
    Sort(h);    
}

源数据:
8,7,9,3,5,4,2

结果:
7,8,
7,8,9,
3,7,8,9,
3,5,7,8,9,
3,4,5,7,8,9,
2,3,4,5,7,8,9,

--------------------------------
Process exited with return value 0
Press any key to continue . . .

分析:根据结果具有插入排序特征
原始数据:
8,7,9,3,5,4,2
代码:
程序代码:
    //截取链表L,从首元节点(8所在结点)开始 
    LNode *p=L->next, *pre;
    //保存首元节点下一个结点 
    LNode *r=p->next;
    //将首元节点的后继指向改为NULL,即L链表被切断,仅剩头结点和首元结点 
    //L:head->8 
    p->next=NULL;
    //p的指向更新为r的节点,即
    //p:7->9->3->5->4->2 
    p=r;
    while(p!=NULL){
        r=p->next;
        pre=L;
        //第一轮:
            p:7->9->3->5->4->2 
            r:9->3->5->4->2
            pre:head->8 
        //第二轮:
            p:9->3->5->4->2 
            r:3->5->4->2
            pre:head->7->8
        while (pre->next!=NULL && pre->next->data<p->data)
            pre=pre->next;  //在有序表中查找插入的前驱结点*pre
        //第一轮:
            pre:head->8
                :head (pre->next->data:8,p->data:7    8>7跳出循环)
        //第二轮:
            pre:head->7->8
                :8 (pre->next==NULL,p->data:9    pre->next==NULL短路判断,跳出循环)
        p->next=pre->next;
        pre->next=p;
        p=r;
           Show(L);
           
        //第一轮:
            p:9->3->5->4->2 
            r:9->3->5->4->2
            pre:head->7->8
        
        //第二轮:
            p:9->3->5->4->2 
            r:9->3->5->4->2
            pre:head->7->8    
    }

大致流程就是说从r保存的子链表挨个取出每个结点
在L这个只有一个结点的链表不断的找到合适的位置插入r的每个结点

不过是爱情,又能走多久
2017-08-06 21:28
GBH1
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:5
帖 子:112
专家分:510
注 册:2017-6-13
得分:0 
回复 5楼 静水且流深
谢谢,写的非常详细,也很清楚。现在明白点了。
2017-08-07 09:04



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-479828-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.091170 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved