【数据结构与算法4】循环/双向链表及应用

  • 循环链表
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
  • 双向链表
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
  • 顺序表和链表的比较
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 线性表的应用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;
#define ElemType int
#define MAXSIZE 100
#include "windows.h"

//顺序表的数据结构
typedef struct {
    ElemType *data;//数组首元素的地址
    int length;
}SqList;

//初始化
void InitList(SqList &L)
{
    L.data = new ElemType[MAXSIZE];
    L.length = 0;
}

//打印线性表
void PrintList(const SqList &L)
{
    printf("输出顺序表的所有元素:");
    for (int i=0;i<L.length;i++)
    {
        printf("%d\t",L.data[i]);
    }
    printf("\n");
}

//创建线性表
void CreatList(SqList &L)
{
    int n;
    printf("请输入要输入的元素个数:");
    cin >> n;
    for (int i = 0;i<n;i++)
    {
        printf("请输入第%d个元素:",(i+1));
        cin >> L.data[i];
        L.length++;
    }
}

合并两个无序线性表
//void MergeLise(SqList &La, SqList &Lb)
//{
//    int La_len = La.length;
//    int Lb_len = Lb.length;
//    int j = 0;
//    for (int i = 0;i < Lb_len;i++)
//    {
//        //遍历A,直到找到等于B.data[i]的元素或没找到才退出
//        while (La.data[j] != Lb.data[i] && j<La_len)
//        {
//            j++;
//        }
//        //没找到,则插入
//        if (j >= La_len)
//        {
//            La.data[La_len] = Lb.data[i];
//            La.length++;
//            La_len++;
//        }
//        j = 0;
//    }
//}

//顺序表的取值
int GetElem(SqList L,int i ,ElemType &e){
    if (i<0 || i>L.length){
        return -1;
    }
    else{
        e = L.data[i];
    }
    return 0;
}

//合并两个无序线性表
void MergeLise(SqList &La, SqList &Lb)
{
    int La_len = La.length;
    int Lb_len = Lb.length;
    ElemType e;
    for (int i = 0;i < Lb_len;i++)
    {
        int ret = GetElem(La,i,e);
        //没找到,则插入
        if (!ret)
        {
            La.data[La_len] = Lb.data[i];
            La.length++;
            La_len++;
        }
    }
}

int main() {
    SetConsoleOutputCP(CP_UTF8);
    SqList A,B;
    //初始化
    InitList(A);
    InitList(B);
    //创建
    CreatList(A);
    CreatList(B);
    //合并
    MergeLise(A,B);

    PrintList(A);
    PrintList(B);

    return 0;
}

  • 有序表的合并
    在这里插入图片描述
    在这里插入图片描述
  1. 用顺序表实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
#include <iostream>
using namespace std;
#define ElemType int
#define MAXSIZE 100
#include "windows.h"

//顺序表的数据结构
typedef struct {
    ElemType *data;//数组首元素的地址
    int length;
}SqList;

//初始化
void InitList(SqList &L)
{
    L.data = new ElemType[MAXSIZE];
    L.length = 0;
}

//打印线性表
void PrintList(const SqList &L)
{
    printf("输出顺序表的所有元素:");
    for (int i=0;i<L.length;i++)
    {
        printf("%d\t",L.data[i]);
    }
    printf("\n");
}

//创建线性表
void CreatList(SqList &L)
{
    int n;
    printf("请输入要输入的元素个数:");
    cin >> n;
    for (int i = 0;i<n;i++)
    {
        printf("请输入第%d个元素:",(i+1));
        cin >> L.data[i];
        L.length++;
    }
}

//合并两个有序线性表到C中

void MergeList(SqList A, SqList B, SqList &C)
{
    int i =0 ,j = 0,k = 0;
    int m = A.length;
    int n = B.length;

    while (i<m && j<n) {
        if (A.data[i] <= B.data[j]) {
            C.data[k] = A.data[i];
            C.length++;
            i++;
            k++;
        } else {
            C.data[k] = B.data[j];
            C.length++;
            k++;
            j++;
        }
    }
        while (i < m) //B已到达表尾,依次将A的剩余元素插人C的最后
        {
            C.data[k] = A.data[i];
            C.length++;
            i++;
            k++;
        }
        while (j < n) //B已到达表尾,依次将A的剩余元素插人C的最后
        {
            C.data[k] = B.data[j];
            C.length++;
            j++;
            k++;
        }

}


int main() {
    SetConsoleOutputCP(CP_UTF8);
    SqList A,B,C;
    //初始化
    InitList(A);
    InitList(B);
    InitList(C);
    //创建
    CreatList(A);
    CreatList(B);
    //合并
    MergeList(A,B,C);
    PrintList(C);
    return 0;
}

  1. 用链表实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要注意的是:因为链表结点之间的关系是通过指针指向建立起来的,所以用链表进行合并不需要另外开辟存储空间,可以直接利用原来两个表的存储空间, 空间复杂度为o(1)。
C与A共用一个头结点,只需改链即可!

#include <iostream>
using namespace std;
#define ElemType int
#define MAXSIZE 100
#include "windows.h"

顺序表的数据结构
//typedef struct {
//    ElemType *data;//数组首元素的地址
//    int length;
//}SqList;
//单链表的数据结构
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

//初始化
void InitList(LinkList &L)
{
    L = new LNode ;
    L->next = NULL;
}

//打印线性表
void PrintList(LinkList L)
{
    printf("输出单链表的所有元素:");
    LinkList p;
    p = L->next;
    while (p)
    {
        printf("%d",p->data);
        p = p->next;
    }
    printf("\n");
}

//尾插法 创建线性表
void CreatList(LinkList &L)
{
    int n;
    printf("请输入要输入的元素个数:");
    cin >> n;
    LinkList r = L;
    for (int i = 0;i<n;i++)
    {
        LinkList p = new LNode;
        printf("请输入第%d个元素",i+1);
        cin >> p->data;
        r->next = p;
        p->next = NULL;
        r = p;
    }
}

//合并两个有序线性表到C中
void MergeList(LinkList A,LinkList B, LinkList &C)
{
    LinkList pa = A->next;//pa指向A的第一个结点
    LinkList pb = B->next;//pb指向B的第一个结点
    C = A;                  //C指向A的头结点,共用
    LinkList pc = C;  //pc指向C的头结点即A的头结点
    while (pa && pb)
    {
        if (pa->data <= pb->data)
        {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }
        else
        {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb; //将非空表的剩余段插入到pc所指结点之后
    delete B;
}


int main() {
    SetConsoleOutputCP(CP_UTF8);
    LinkList A,B,C;
    //初始化
    InitList(A);
    InitList(B);
    InitList(C);
    //创建
    CreatList(A);
    CreatList(B);
    PrintList(A);
    PrintList(B);
    //合并
    MergeList(A,B,C);
    PrintList(C);
    return 0;
}

  • 案例分析与实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
#include <iostream>
using namespace std;
#define ElemType int
#define MAXSIZE 100
#include "windows.h"

//定义数据结构
typedef struct BookNode{
    int coef;
    int exp;
    struct BookNode*next;
}BookNode,*BookList;

//初始化
void InitBookNode(BookList &L)
{
    L = new BookNode;
    L->next = NULL;
}

//尾插法 创建多项式单链表
void CreatList(BookList &L, int n){
    BookList r;
    r = L;
    for (int i=0;i<n;i++)
    {
        BookList p = new BookNode ;
        printf("请输入第%d个项的系数:",i+1);
        cin >> p->coef;
        printf("请输入第%d个项的指数:",i+1);
        cin >> p->exp;
        r->next = p;
        p->next = NULL;
        r = p;
    }
}

//打印多项式
void PrintBook(BookList L)
{
    BookList p = L->next;
    while(p)
    {
        cout << p->coef << "*X^" << p->exp << "+" ;
        p = p->next;
    }
    cout << "0" << endl;
}

//多项式相加
void AddPoly(BookList &A , BookList &B, BookList &C)
{
    BookList pa = A->next;//pa指向A的第一个结点
    BookList pb = B->next;//pb指向B的第一个结点
    C = A;                  //C指向A的头结点,共用
    BookList pc = C;        //pc指向C的头结点即A的头结点
    while (pa && pb)
    {
        if (pa->exp < pb->exp)
        {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }
        else if (pa->exp > pb->exp)
        {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
        else//指数相等时
        {
            int x = pa->coef + pb->coef;
            if (x) //指数相等且系数和不为零时相加并保存到A节点,同时删除B节点
            {
                pc->next = pa;
                pc = pa;
                pc->exp = pa->exp;
                pc->coef = x;
                pa = pa->next;
                //删除B节点
                BookList pb_q = pb;
                pb = pb->next;
                delete pb_q;
            }
            else
            {
                BookList pa_q = pa;
                pa = pa->next;
                delete pa_q;
                BookList pb_q = pb;
                pb = pb->next;
                delete pb_q;
            }
        }
    }
    while(pa)
    {
        pc->next = pa;
        pc = pa;
        pa = pa->next;
    }
    while(pb)
    {
        pc->next = pb;
        pc = pb;
        pb = pb->next;
    }
}

int main() {
    SetConsoleOutputCP(CP_UTF8);
    BookList A,B,C;
    //初始化
    InitBookNode(A);
    InitBookNode(B);
    InitBookNode(C);
    //创建
    CreatList(A,4);
    CreatList(B,3);
    PrintBook(A);
    PrintBook(B);
    //合并
    AddPoly(A,B,C);
    PrintBook(C);
    return 0;
}

请输入第1个项的系数:7
请输入第1个项的指数:0
请输入第2个项的系数:3
请输入第2个项的指数:1
请输入第3个项的系数:9
请输入第3个项的
指数:8
请输入第4个项的系数:5
请输入第4个项的指数:17
请输入第1个项的系数:8
请输入第1个项的指数:1
请输入第2个项的系数:22
请输入第2
个项的指数:7
请输入第3个项的系数:-9
请输入第3个项的指数:8
7*X^0+3*X^1+9*X^8+5*X^17+0
8*X^1+22*X^7+-9*X^8+0
7*X^0+11*X^1+22*X^7+5*X^17+0

Process finished with exit code 0
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姬霓钛美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值