链表排序问题

going__ 2017-12-15 09:47:24
请问对一个单链表进行排序(使用指针交换的方法不是交换链表里的数据,因为数据比较多),具体的核心算法是怎样的啊?求大家帮帮忙!!!
...全文
219 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
JJ1M8 2017-12-21
  • 打赏
  • 举报
回复
关于单链表的排序: 可以用冒泡排序法,先两个数据节点的数据域---进行比较,把大的往前或者往后排,比较n-1轮;数据就可以是从大到小排序了. 具体的交换顺序的方法就用指针存放的地址的改变实现交换位置: 但是冒泡法显然操作要比较多.
自信男孩 2017-12-20
  • 打赏
  • 举报
回复
引用 3 楼 qq_30780133 的回复:
[quote=引用 2 楼 cfjtaishan 的回复:] 链表可以考虑使用插入排序方法: 以下的例子仅供参考:
#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *create_list();
struct ListNode *deletem(struct ListNode *L, int m);
struct ListNode *my_deletem(struct ListNode *L, int m);

void Insertsort(struct ListNode **L);

void printlist(struct ListNode *L)
{
    struct ListNode *p = L;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main(void)
{
    int m;
    struct ListNode *L = create_list();

    printlist(L);
    Insertsort(&L);
    printlist(L);

    printf("Please input your delete number: ");
    scanf("%d", &m);
    L = deletem(L, m);
    printlist(L);

    return 0;
}

/* 带哨兵的链表插入排序*/
void Insertsort(struct ListNode **L)
{
    struct ListNode *p,*q,*r,*u;
    p = (*L)->next;
    (*L)->next = NULL;
    while(p!=NULL)
    {
        r = *L;
        q = (*L)->next;
        while(q !=NULL && q->data <= p->data)
        {
            r = q;
            q = q->next;
        }
        u=p->next;
        p->next=r->next;
        r->next=p;
        p=u;
    }
}

struct ListNode *create_list()
{
    struct ListNode *head,*p1,*p2;
    int m;
    int size = sizeof(struct ListNode);

    printf("Input a interge (-1 stop input)\n");
    p1 = (struct ListNode*)malloc(size);
    scanf("%d", &m);
    p1->data = m;
    head = NULL;

    while (p1->data != -1) {
        if(head == NULL)
            head = p1;
        else
            p2->next = p1;
        p2 = p1;
        scanf("%d", &m);
        p1 = (struct ListNode *)malloc(size);
        p1->data = m;
    }
    free(p1);
    p2->next = NULL;

    return head;
}

struct ListNode *deletem( struct ListNode *L, int m )
{
    struct ListNode *ptr, *ptr1;
    while( L != NULL && ( L->data == m) )
    {
        ptr1 = L;
        L = L->next;
        free(ptr1);
    }
    if( L == NULL )
        return NULL;
    ptr = L;
    ptr1 = L->next;
    while( ptr1 != NULL)
    {
        if( ptr1->data == m )
        {
            ptr->next = ptr1->next;
            free(ptr1);
        }
        else
            ptr = ptr1;
        ptr1 = ptr->next;
    }
    return L;
}
链表创建,输出和删除某个节点,插入排序(带哨兵的)
这个代码好像有bug哦,输入的数中有0的话,0的顺序是错的[/quote] 恩,输入的第一个应该是哨兵。 建议只看带哨兵的插入排序吧,其他函数,比如链表创建,链表删除和链表输出都是针对不带哨兵的情况,但是这个排序是针对带哨兵的。
going__ 2017-12-20
  • 打赏
  • 举报
回复
引用 2 楼 cfjtaishan 的回复:
链表可以考虑使用插入排序方法: 以下的例子仅供参考:
#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *create_list();
struct ListNode *deletem(struct ListNode *L, int m);
struct ListNode *my_deletem(struct ListNode *L, int m);

void Insertsort(struct ListNode **L);

void printlist(struct ListNode *L)
{
    struct ListNode *p = L;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main(void)
{
    int m;
    struct ListNode *L = create_list();

    printlist(L);
    Insertsort(&L);
    printlist(L);

    printf("Please input your delete number: ");
    scanf("%d", &m);
    L = deletem(L, m);
    printlist(L);

    return 0;
}

/* 带哨兵的链表插入排序*/
void Insertsort(struct ListNode **L)
{
    struct ListNode *p,*q,*r,*u;
    p = (*L)->next;
    (*L)->next = NULL;
    while(p!=NULL)
    {
        r = *L;
        q = (*L)->next;
        while(q !=NULL && q->data <= p->data)
        {
            r = q;
            q = q->next;
        }
        u=p->next;
        p->next=r->next;
        r->next=p;
        p=u;
    }
}

struct ListNode *create_list()
{
    struct ListNode *head,*p1,*p2;
    int m;
    int size = sizeof(struct ListNode);

    printf("Input a interge (-1 stop input)\n");
    p1 = (struct ListNode*)malloc(size);
    scanf("%d", &m);
    p1->data = m;
    head = NULL;

    while (p1->data != -1) {
        if(head == NULL)
            head = p1;
        else
            p2->next = p1;
        p2 = p1;
        scanf("%d", &m);
        p1 = (struct ListNode *)malloc(size);
        p1->data = m;
    }
    free(p1);
    p2->next = NULL;

    return head;
}

struct ListNode *deletem( struct ListNode *L, int m )
{
    struct ListNode *ptr, *ptr1;
    while( L != NULL && ( L->data == m) )
    {
        ptr1 = L;
        L = L->next;
        free(ptr1);
    }
    if( L == NULL )
        return NULL;
    ptr = L;
    ptr1 = L->next;
    while( ptr1 != NULL)
    {
        if( ptr1->data == m )
        {
            ptr->next = ptr1->next;
            free(ptr1);
        }
        else
            ptr = ptr1;
        ptr1 = ptr->next;
    }
    return L;
}
链表创建,输出和删除某个节点,插入排序(带哨兵的)
这个代码好像有bug哦,输入的数中有0的话,0的顺序是错的
自信男孩 2017-12-17
  • 打赏
  • 举报
回复
链表可以考虑使用插入排序方法: 以下的例子仅供参考:
#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *create_list();
struct ListNode *deletem(struct ListNode *L, int m);
struct ListNode *my_deletem(struct ListNode *L, int m);

void Insertsort(struct ListNode **L);

void printlist(struct ListNode *L)
{
    struct ListNode *p = L;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

int main(void)
{
    int m;
    struct ListNode *L = create_list();

    printlist(L);
    Insertsort(&L);
    printlist(L);

    printf("Please input your delete number: ");
    scanf("%d", &m);
    L = deletem(L, m);
    printlist(L);

    return 0;
}

/* 带哨兵的链表插入排序*/
void Insertsort(struct ListNode **L)
{
    struct ListNode *p,*q,*r,*u;
    p = (*L)->next;
    (*L)->next = NULL;
    while(p!=NULL)
    {
        r = *L;
        q = (*L)->next;
        while(q !=NULL && q->data <= p->data)
        {
            r = q;
            q = q->next;
        }
        u=p->next;
        p->next=r->next;
        r->next=p;
        p=u;
    }
}

struct ListNode *create_list()
{
    struct ListNode *head,*p1,*p2;
    int m;
    int size = sizeof(struct ListNode);

    printf("Input a interge (-1 stop input)\n");
    p1 = (struct ListNode*)malloc(size);
    scanf("%d", &m);
    p1->data = m;
    head = NULL;

    while (p1->data != -1) {
        if(head == NULL)
            head = p1;
        else
            p2->next = p1;
        p2 = p1;
        scanf("%d", &m);
        p1 = (struct ListNode *)malloc(size);
        p1->data = m;
    }
    free(p1);
    p2->next = NULL;

    return head;
}

struct ListNode *deletem( struct ListNode *L, int m )
{
    struct ListNode *ptr, *ptr1;
    while( L != NULL && ( L->data == m) )
    {
        ptr1 = L;
        L = L->next;
        free(ptr1);
    }
    if( L == NULL )
        return NULL;
    ptr = L;
    ptr1 = L->next;
    while( ptr1 != NULL)
    {
        if( ptr1->data == m )
        {
            ptr->next = ptr1->next;
            free(ptr1);
        }
        else
            ptr = ptr1;
        ptr1 = ptr->next;
    }
    return L;
}
链表创建,输出和删除某个节点,插入排序(带哨兵的)
赵4老师 2017-12-16
  • 打赏
  • 举报
回复
将两个有序链表合并成一个有序链表 http://blog.csdn.net/lalor/article/details/7429989

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧