单链表合并排序实现

原题是要实现两个已排序的单链表合并后还是已排序,但我在网上查了很多都无法直接实现.对于初学者给个算法是没多大用的,下面给出完整代码.主要思路就是先接尾再排序.而一般书是直接开始分情况if...else if...else嵌套排序.比较复杂.

/*关键:两个有序单链表的合并:其实本程序可以实现任意两个单链表的合并排序,思想就是
*1.建两个链表2.合并两个链表3.对合并后的链表排序4.打印
*关键函数:linkDList 直接连接两个链表;selectsort 单链表的选择排序*/
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "malloc.h"
#include "windows.h"//system()所在
typedef char ElemType;
typedef struct dNode
{//声明单链表结点类型
    ElemType data;    //数据域,注意此单链表结点类型是字符型.有什么办法可以泛化呢?
    struct dNode *next;    //指针域
}LNode, *LinkList;    //定义此结构体变量struct dNode a或LNode a;定义此结构体的指针struct dNode *p或LNode *p或LinkList p都是没区别的

//此函数本程序没用到,只是为了和后面的CreateDListTail对应
LinkList CreateDListHead(LinkList head)
{
    ElemType temp;
    LinkList p;
    printf("请输入结点值");
    fflush(stdin);
    scanf("%c", &temp);
    while (temp!=‘0‘)
    {
        if ((‘A‘ <= temp&&temp <= ‘Z‘) || (‘a‘ <= temp&&temp <= ‘z‘))
        {
            p = (LinkList)malloc(sizeof(LNode));
            p->data = temp;
            p->next = head->next;
            head->next = p;
        }
        printf("请输入结点值(输入0结束):");
        fflush(stdin);
        scanf("%c", &temp);
    }
    return head;
}
LinkList CreateDListTail(LinkList Tail)  //尾插法建立链表
{
    ElemType temp;
    LinkList s, r;
    printf("请输入结点值");
    fflush(stdin);
    scanf("%c", &temp);
    r = Tail;
    while (temp!=‘0‘)
    {
        if ((‘A‘ <= temp&&temp <= ‘Z‘) || (‘a‘ <= temp&&temp <= ‘z‘))
        {
            s = (LinkList)malloc(sizeof(LNode));
            s->data = temp;
            r->next = s;
            r = s;
        }
        printf("请输入结点值(输入0结束):");
        fflush(stdin);
        scanf("%c", &temp);
    }
    r->next = NULL;
    return Tail;
}
void PrintDList(LinkList head)
{
    LinkList p;
    int i = 0;
    p = head->next;//p指向第一个结点.这一步原head后的结点都会跑到p后
    while (p != NULL)
    {
        i++;
        printf("第%d个元素是:", i);
        printf("%c\n", p->data);
        p = p->next;
    }
    printf("\n");
}
void linkDList(LinkList S, LinkList T)
{/*连接2个单链表*/
    LinkList temp = S;
    while (temp->next != NULL)
        temp = temp->next;
    temp->next = T->next;
    PrintDList(S);
}
void selectsort(LinkList A)
{//将降序排列
    ElemType t;
    LinkList p, q, s;//q,s比较
    if ((A->next) && (A->next->next))    //链表为空或只有一个结点时不用排序
    {
        p = A->next;
        while (p->next)
        {
            q = p->next;
            s = p;
            while (q)
            {
                if (q->data > s->data)
                {
                    t = q->data;
                    q->data = s->data;
                    s->data = t;
                }
                q = q->next;
            }//endwhile 交换s结点和p结点的数据
            p = p->next;
        }//endwhile
    }//endif
    PrintDList(A);
}//endselectsort

void main()
{
    LinkList A=(LinkList)malloc(sizeof(LNode));
    LinkList B = (LinkList)malloc(sizeof(LNode));
    CreateDListTail(A);
    PrintDList(A);
    CreateDListTail(B);
    PrintDList(B);
    linkDList(A, B);
    selectsort(A);
    system("PAUSE");
    free(A);
    free(B);
}

代码通过VS 2013 + win 7 64 ;编译通过可运行,静态分析未通过,主要提示内存安全,API没返回值.

这个程序仅仅实现题目功能,一点都不完美.初学者能运行过谢天谢地了.

此外,代码的main部分应该可以简化吧,但是我不会.请前辈们指教.

时间: 2024-12-26 18:43:17

单链表合并排序实现的相关文章

链表习题(7)-将两个递增单链表合并成一个递减单链表

1 /*将两个递增单链表合并成一个递减单链表*/ 2 /* 3 算法思想:两个链表已经按元素值递增次序排序,将其合并时,均从第一个结点起进行比较,将较小的 4 结点链入链表中,同时后移工作指针.由于结果链表是递减的,故使用头插法建立新链表.比较结束后, 5 可能会有一个链表非空,此时用头插法将剩下的结点依次插入新链表中即可. 6 */ 7 void Union_List(LinkList& La,LinkList& Lb) 8 { 9 LNode *r, *pa = La->next

单链表的排序 快速排序 归并排序 quicksort mergesort

原理都很简单,关键是某些边界能否正确写对: #include<iostream> #include<stdio.h> using namespace std; class Node { public: int val; Node* next; Node(int val = 0):val(val),next(NULL){ } }; Node* quicksort(Node* head, Node* tail) { Node *res1 = NULL, *res2 = NULL; No

从单链表中删除最大的元素,单链表元素排序

public class LinkList { public Node head; public LinkList() { head = new Node(); head.next = null; } //尾插法 public void createByTail(int[] arr, int n) { Node tail = head; for(int i=0; i<n; i++) { Node c = new Node(arr[i]); tail.next = c; tail = c; } t

单链表 --- 合并两个单链表

合并单链表 --> 一.解决方法: 确保两个单链表不为空,且二者皆有序(若无序,则先进行排序) 创建新的单链表,并比较原本两个单链表数据大小,较小者置于新单链表中 逐步将两个单链表的数据置于新单链表中,直至二者为空 二.程序代码: ListNode* MergeList(ListNode *L1,ListNode *L2)//合并两个单链表 { ListNode *newHead=NULL; ListNode *tail=NULL; if(L1==NULL) { return L2; } if(

链表——单链表的排序

题目要求: 对单链表进行从小到大排序,要求时间复杂度O(N*logN),空间复杂度O(1): 思路: 因时间复杂度要求为O(N*logN),简单排序(时间复杂度为O(N*N))均不可用, 故可以考虑归并排序的思想,归并排序对数组操作空间复杂度为O(n),但对链表为O(1),因为每次只在merge函数中创建了一个辅助的链表头结点ListNode temp=new ListNode(0); 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二: 2)递归地对左半部分进行归并排序: 3)递

单链表的排序

单链表的逆序: 由于链表不同于数组一样,所以将排好序的结点放到另一个链表中去,然后再由头指针指向该链表. 1 void Link::Sort(Node * Head) { 2 3 Node * Root = NULL; // 头指针,作为一个新链表指针,将所有结点链接到这里 4 Node * Tail = NULL; // 尾指针 5 Node * pMin = NULL; // 作为待操作链表结点中最小结点的前驱 6 Node * min = NULL; // 最小结点的指针 7 Node *

Leetcode:Reorder List 单链表重排序

Given a singly linked list L: L0→L1→-→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do this in-place without altering the nodes' values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}. 分析:观察重排前和重排后的序列,发现单链表前半部分各元素的相对顺序保持不变,而后半部分逆序.因

数据结构单链表就地排序

void LinListSort(LinList<T> &L) { ListNode<T> *curr, *pre, *p, *q; p = L.head->next; //原单链表L.head->next = NULL; //新单链表 while(p != NULL) { curr = L.head->next; pre = L.head; while(curr != NULL && curr->data <= p->d

面试题 - 无序单链表,排序

有一个单链表,无序,给定一个值,将链表中小于这个值的节点放置于链表前面,节点之间相对顺序不变. 这个题目我是这样想的,我们遍历单链表,当遇到大于指定指的节点群后,再其后面查找小于指定值的节点群,然后交换两个节点群的位置. 思路有了,大致的代码: function LinkNode(data){ this.data = data; this.next = null; } function LinkList(data){ this.head = new LinkNode(data); } LinkL