实现对单链表的赋值、去重、拆分、排序。

在一个带头结点的单链表A中,自行输入A中的元素值,请实现:

(1)将链表A中值相同的结点,仅保留第一次出现的结点;

(2)将新得到的A链表,根据值的奇偶性进行拆分,拆分为有序的链表B和链表C。

B、C满足:链表B为值递增排序的奇数链表,链表C为值递增的偶数链表。 

实验要求:

(1)实验顺序不能颠倒;

(2)每一小问完成后输出结果;

(3)对算法进行复杂性分析。

代码内容:

#include<iostream>
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <malloc.h>
using namespace std;


/*定义链表*/
typedef struct Node 
{
    int data;
    struct Node* next;
}LinkList,*LNode;


/*给链表赋值并添加头节点*/
void create(LinkList*& A, int a[], int n) //传入链表A,数组a[],链表长度n
{
    int i;
    LinkList* s, * r;
    A = (LinkList*)malloc(sizeof(LinkList)); //给链表A分配内存空间,同时产生头节点,将A指向此头节点
    r = A;
    for (i = 0; i < n; i++) 
    {
        s = (LinkList*)malloc(sizeof(LinkList)); //给链表s分配内存空间,并插入节点
        s->data = a[i]; //将数组a[]的值赋值给链表
        r->next = s;
        r = s;
    }
    r->next = NULL;
}


/*在单链表中删除值相同的多余结点*/
void deleteLinkList(LinkList*& A) //传入链表
{
    LinkList* p = A->next, * s, * q;
    while (p != NULL) //第一重循环将p的位置固定下来,进入第二重循环与后面的遍历指针p所指向的结点比较看值是否相等
    {
        q = p;//将q指向p的结点,比较数据的值是否相等
        while (q->next != NULL) //用q遍历p之后的每一个结点
        {
            if (q->next->data == p->data) //如果q的值与p的值相同
            {
                s = q->next;//s保留需要删除的结点
                q->next = s->next;//将需要删除的节点的前后结点相接
                free(s);//将需要删除的结点释放
            }
            else
            {
                q = q->next;//如果q的值与p的值不相同,则q移向后一个结点
            }
        }
        p = p->next;//将p移向后一个结点
    }
}


/*打印链表*/
void print(LinkList* L)//传入链表
{
    LinkList* p = L->next;
    while (p != NULL) //链表结点对应的值不为空时打印值
    {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}


/*拆分成奇数链表和偶数链表*/
LNode spilt(LinkList* B , LinkList* C)
{
    LinkList* p = B;
    
    C = (LinkList*)malloc(sizeof(LinkList)); //给链表C分配内存空间
    C->next = NULL; //链表C结点为空
    LinkList* q = C;

    LinkList* r;

    while (p->next != NULL)//将p结点不为空时
    {
        if (p->next->data % 2 == 0)//如果结点对应的值为偶数
        {
            r = p->next;//r保留这个偶数对应的结点
            p->next = p->next->next;//将这个偶数前后的接连链接起来,即在原链表中删除这个偶数所对应的结点//q指针向下移动
            q->next = r;//储存这个偶数对应的结点
            r->next = NULL;//r结点为空
            q = q->next; //将q移向后一个结点
        }
        else
        {
            p = p->next; //将p移向后一个结点
        }
    }

    return C;//返回偶数链表B,且此时链表L已经成为一个奇数链表
}


/*对链表进行排序*/
void Sort(LinkList* L)
{
    LinkList* p, * q;
    int t;
    p = L->next;//p指向首元结点
    while (p != NULL)//第一重循环将p的位置固定下来,进入第二重循环与后面的遍历指针p所指向的结点之间相互比较大小
    {
        q = p->next;//将q指向p的下一个结点,进行数据之间的大小比较
        while (q != NULL)//第二重循环就是不断将指针q后移,与p所指向的结点数据进行大小比较,数据互换
        {
            if (p->data > q->data)//冒泡排序
            {
                t = p->data;//将数据寄存在t中,进行互换
                p->data = q->data;
                q->data = t;
            }
            q = q->next;//遍历p之后的每一个值
        }
        p = p->next;//遍历链表中的每一个值

    }
}


int main()
{
    int n, i;
    LinkList* A;//创建链表A

    cout << "请输入链表A长度:" << endl;
    cin >> n;//输入链表A的长度

    cout << "请输入在链表A储存的数据:" << endl;
    int a[1000];//创建数组a[]
    for (i = 0; i < n; i++) //对数组A进行赋值
    {
        cin >> a[i];
    }

    create(A, a, n);//将数组a[]中的值传入链表A并添加头节点
    
    cout << "对链表A去重并打印:" << endl;
    deleteLinkList(A);//对链表A进行去重
    print(A);//打印去重之后的链表A

    
    LinkList* B = A;//创建与去重之后的链表A相等的链表B
    LinkList* c = NULL ;//创建空链表c
    LinkList* C = spilt(B, c);//创建链表C,将函数spilt()的返回值(偶数链表)赋值给链表C
    //函数spilt()将链表B中的偶数所对应的结点删除,使链表B变成了奇数链表


    cout << "对奇数链表B中的奇数排序并打印:" << endl;
    Sort(B);
    print(B);
    
    cout << "对偶数链表C中的偶数排序并打印:" << endl;
    Sort(C);
    print(C);


    return 0;

}

输出示例:

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5Y2D56an5bm055qE6ZKg56a75a2Q,size_19,color_FFFFFF,t_70,g_se,x_16

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值