线性表--数据结构设计与操作

单链表

1.单链表的定义:

typedef struct LNode{
    Elemtype data;
    struct Lnode *next;
}LNode ,*LinkList;

    //单链表的数据结构(手写)
#include<iostream>
#include<vector>
#include<algorithm>

typedef int TypeElem;
//单链表的定义
t
    ypedef struct LNode {
    TypeElem data;
    struct LNode* next;
}LNode,*LinkList;

//初始化单链表(带头结点)
boolInitLinkList_H(LinkList& L) {
    L = (LNode*)malloc(sizeof(LNode));//L = new LNode;等价写法c++
    L->next = NULL;
    return true;
}
//不带头结点的单链表初始化
bool InitLinkList_(LinkList&L){
    L = NULL;
    return ture;
}
/*求表长O(n),扫描链表*/
int Length(LinkList&L){
    int ltn=0;
    p = L->next;
    while(p){
        p=p->next;
        len++;
    }
    return len;
    }

/*按位序查找节点*/
LNode* GetElem(LinkList L,int pos){
        LNode*p = L->next;
        int j=1;
        while(p&&j<=pos){
            j++;
            p = p->next;
        }
    return p;//返回第pos个节点的指针或NULL
}
/*按值查找表节点*/
LNode*LocateElem(LinkList&L,int val){
        LinkList p = L->next;
        while(p && p->data!=val)
            p = =->next;
        return p;
    }
/*插入节点O(n)时间主要消耗在查找到第i-1个节点上,若在指定节点后插入新节点则只需O(1)*/
bool ListInsert(LinkList&L,int pos,int e){

        LinkList p =L->next;

        int j=1;
        while(p && j<pos-1)
            p = p->next;
        if(!p)
            return false;
        LNode*s = (LNode*)malloc(sizeof(LNode));
        s->data = e;
        s->next =p->next;
        p->next = s;
        return true;
    }
/* 删除节点*/
bool ListDelete(LinkList&L,int pos,int &e){
        LinkList p = L->next;

        while(p&&j<pos-1){
            p = p->next;
            j++;
        }
        if(!p)return false;//链表为空
        LNode*q =p->next;
        e = q->data;//用e返回被删除的元素的值
        p->next = q->next;
        free(q);
        return true;

    }
bb2ad43e-72dc-4264-a176-46f0767c916e
2.单链表的插入与删除

2-1按位序插入(在某一节点的后面插入新节点)

//带头结点
bool ListInsert(LinkList &L,int i,Elemtype e){
    if(i<1)
        return false;
    LNode*p;
    int j =0;
    p = L;
    while(p!=NULL && j<i-1){//找到第i-1个节点(节点i的前驱节点)
        p = p->next;
        j++;
    }
    if(p==NULL)//i值不合法
        return false;
    //插入操作(可封装为函数)
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return true;  
}
aa9534f4-63c8-49c2-8a75-a35676d1f9fb
3.单链表的建立(头插法/尾插法)

//迭代法
/*假设链表为 1→2→3→∅我们想要把它改成  ∅←1←2←3。
算法设计基本思想:
    在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用
时空复杂度分析:
    时间复杂度O(n),只需扫描一遍链表
    空间复杂度O(1),原地逆置
*/
ListNode* reverseList(ListNode* head) {
        ListNode*pre = nullptr;//节点的前一个结点
        ListNode*cur = head;
        while(cur){
            ListNode*ne = cur->next;//存储当前结点的后继节点
            cur->next = pre;//将当前节点的后继节点改为其前驱节点
            pre = cur;
            cur = ne;//迭代更新当前节点
        }
        return pre;
    }


//递归法逆置

    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) {
            return head;
        }
        ListNode* newHead = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return newHead;
    }


06eebb10-b37a-4e1e-898c-dea794fb482c

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/*在带头结点的单链表L中删除所有值为x的节点,并释放其空间*/
void DeleteX(LinkList&L,int x){
    LNode*p = L;
    while(p->next){
        if(p->next-val==x){
            LNode*q = p->next;
            p->next = q->next;q
            free(q);
        }else{
            p=p->next;
        }
    }
}
    int DeleteMinEle(LinkList& L,int e) {
    if (L->next == NULL) {
        // List is empty
        return -1; // or any other appropriate value
    }

    LNode* min_pre = L;
    LNode* min_node = L->next;
    LNode* p = L->next->next; // Start from the second node
    LNode* pre = L->next;

    while (p) {
        if (p->data < min_node->data) {
            min_pre = pre;
            min_node = p;
        }
        pre = p;
        p = p->next;
    }

    e= min_node->data;
    min_pre->next = min_node->next;
    free(min_node);

    return e;//返回最小元素
}

/*就地逆置带头结点的单链表*/
void ReverseLinkList_H(LinkList& L) {
    if (L->next == NULL|| L->next->next==NULL)return;//链表为空或只有一个数据节点,无需逆置
    LNode* p = L->next;
    LNode* pre = NULL;
    while (p != NULL) {
        LNode* ne = p->next;
        p->next = pre;
        pre = p;
        p = ne;
    }
    L ->next=pre;//切记逆置后要更新头节点!!!
    return;
}

C = a 1 , b 1 , a 2 , b 2 , ⋅ ⋅ ⋅ , a n , b n C={a_1,b_1,a_2,b_2,···,a_n,b_n} C=a1,b1,a2,b2,⋅⋅⋅,an,bn为线性表,才用带头结点的单链表存放,设计一个就地工作算法,将其拆分为两个线性表 A = a 1 , a 2 , ⋅ ⋅ ⋅ , a n , B = b 1 , b 2 , ⋅ ⋅ ⋅ , b n A={a_1,a_2,···,a_n},B={b_1,b_2,···,b_n} A=a1,a2,⋅⋅⋅,an,B=b1,b2,⋅⋅⋅,bn

    void breakLinkList(LinkList&L){
        //先获取单链表的长度
        int len = Length(L);
        LNode*curr=L->next;
        //L->next=NULL;//摘取原链表的头节点
        LinkList A= new LNode;
        LinkList B = new LNode;
       A->next=NULL,B->next=NULL;
        LNode* s1=A,*s2=B;
        for(int i=1;i<=len;i++){
            LNode*ne = p->next;
            if(i&1){
               
                p->next=NULL;
                s1->next =p;
                s1 = p;
            }else{
                p->next=NULL;
                s2->next =p;
                s2 = p;
            }
            p = ne;
        }
        printList(A);
        printList(B);

    }

对一个有序单链表去重处理O(n)

//对一个有序单链表去重处理O(n)
void DeleteMulEle(LinkList& L) {
    if (L == NULL || L->next == NULL) // If the list is empty or has only one node, no duplicates to remove
        return;
    LNode* p = L->next;
    LNode* pre = L;
    while (p!=NULL&&p->next!=NULL) {
        if (p->data != p->next->data) {
            pre = p;
        }
        else {
            LNode* q = p->next;
            p->next = q->next;
            free(q);
        }
        p = p->next;
    }

}

已知两个单链表A和B分别表示两个集合,其元素递增有序,编写函数求A与B的交集,并存放于A链表中。

void MergePublicElem(LinkList& A, LinkList& B) {
    /*
    算法设计基本思想:
        由于链表元素单调有序,故采用归并的思想提取公共元素。
    时间复杂度:O(lenA+lenB);
    空间复杂度:O(1);
    */
    LNode* pa = A->next;
    LNode* pb = B->next;
    LNode* La = A->next;
    LNode* pre = A;
    while (pa != nullptr && pb != nullptr) {
        if (pa->data == pb->data) {
            La->data = pa->data;
            pre = La;
            La = La->next;
            pa = pa->next;
            pb = pb->next;
        }
        else if (pa->data < pb->data) {
            pa = pa->next;
        }
        else {
            pb = pb->next;
        }
    }
    pre->next=NULL;
    delete La;
    printList(A);
    return;
}

两个整数序列A和B已经存放到两个单链表中,请设计算法,判断B序列是否是A序列的连续子序列。

bool AIsSubseqB(LinkList&A,LinkList &B){
/*
  算法设计基本思想:
    本题采用朴素匹配算法实现
    时间复杂度:O(nm);
    空间复杂度:O(1);      
*/
    LNode*pa= A->next;
    LNode*pb = B->next;
    LNode*pre = A;
    while(pa&&pb){
       if(pa->data== pb->data){
            pa = pa->next;
            pb = pb->next;
        }else{//如果值不相等
            pre = pre->next;
            pa = pre;//A链表新的开始比较的节点
            pb = B->next;//pb重新指向B链表首节点

        }  
    }
    if(!pb) return true;
    return false;
}

判断一个带头结点的循环双链表是否对称

#include<iostream>

typedef int ElemType;
//双链表的定义
typedef struct Node{
	ElemType data;
	Node* pre;
	Node* next;
}DNode, * DLinkList;

//初始化带头结点的循环双链表
bool InitDlist_H(DLinkList& L) {
	L = new DNode;
	L->pre = L;
	L->next = L;
	return true;
}
bool InsertElems(DLinkList& L, ElemType x) {
	DNode* s = new DNode;
	s->data = x;
	s->next = L->next;
	L->next->pre = s;
	s->pre = L;
	L->next= s;
	//L->pre = s;
	return true;
}
//头插法
void Print(DLinkList L) {
	auto p = L->next;
	while (p != L) {
		std::cout << p->data << "->";
		p = p->next;
	}
	std::cout << '\n';
}
bool issymmetry(DLinkList L) {
    /*
    Algorithm design:
    Scan from both ends of the list towards the middle, comparing corresponding elements.
    Time complexity: O(n)
    Space complexity: O(1)
    */
    DNode *left = L->next; // Points to the first node
    DNode *right = L->pre; // Points to the last node

    while (left != right && right->next != left) {
        if (left->data != right->data)
            return false;
        left = left->next;
        right = right->pre;
    }
    return true;
}

int main()
{
	DLinkList L;
	InitDlist_H(L);
	for (int i = 1; i <= 9; i++)
		InsertElems(L, i);
	Print(L);
	printf("%d\n",issymmetry(L));

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/601069.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何解决3D模型变黑或贴图不显示的问题---模大狮模型网

在进行3D建模和视觉渲染时&#xff0c;经常会遇到模型表面变黑或贴图不显示的问题&#xff0c;这可能严重影响最终视觉效果的质量。这些问题通常与材质设置、光照配置或文件路径错误有关。本文将探讨几种常见原因及其解决方法&#xff0c;帮助3D艺术家和开发者更有效地处理这些…

☺☺☺☺☺☺☺栈的应用习题:有效的括号☺☺☺☺☺☺☺

目录 一解题思路&#xff1a; 二对解答代码分析&#xff1a; 三解答代码展示&#xff1a; 即浅学栈的创建后&#xff0c;可以简单利用其性质&#xff08;先进后出&#xff0c;后进先出&#xff09;来完成对一些题目的解答 如&#xff1a; 一解题思路&#xff1a; 这里我们可…

[法规规划|数据概念]金融行业数据资产和安全管理系列文件解析

“ 金融行业在自身数据治理和资产化建设方面一直走在前列。” 一直以来&#xff0c;金融行业由于其自身需要&#xff0c;都是国内开展信息化建设最早&#xff0c;信息化程度最高的行业。 同时&#xff0c;金融行业的数据治理、数据资产化以及过程中的管理要求和安全要求与其他…

Hive Partitioned Tables 分区表

Hive Partitioned Tables 分区表 1.分区表概念 Hive分区表&#xff08;Partitioned Tables&#xff09;是一种用于管理大量数据的机制&#xff0c;它可以将数据分散到不同的目录或分区中&#xff0c;以提高查询性能、优化数据存储和管理。 这种表结构可以根据某个列的值进行分…

【Ansible】ansible-playbook剧本

playbook 是ansible的脚本 playbook的组成 1&#xff09;Tasks&#xff1a;任务&#xff1b;通过tasks 调用ansible 的模板将多个操作组织在一个playbook中运行 2&#xff09;Variables&#xff1a;变量 3&#xff09;Templates&#xff1a;模板 4&#xff09;Handles&#xf…

基于C++从0到1手写Linux高性能网络编程框架(超清)

基于C从0到1手写Linux高性能网络编程框架(超清) TIME_WAIT状态存在原因有两点&#xff1a; 其一是可靠的中止tcp连接&#xff1b; 其二是保证让延迟的tcp报文有足够的时间被识别&#xff1b; 客户端在关闭连接阶段需要处理收到重复的结束报文&#xff0c;然后回复最后的ACK…

网络网络层之(4)IPv4协议

网络网络层之(1)IPv4协议 Author: Once Day Date: 2024年4月4日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…

IDEA远程连接docker服务,windows版docker desktop

1.windows上安装docker desktop docker desktop下载地址&#xff1a;Docker Desktop: The #1 Containerization Tool for Developers | Docker 有的windows系统不支持安装docker desktop 安装完之后我们可以直接打开&#xff0c;可以选择不登录使用 我们用IDEA连接到docker …

什么是 AI Agent ?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 讲解的同时&#xff0c;也给你推荐一些实用的学习资源。 AI agent &#xff08;智能体 / 代理&#xff09;这个词儿最近非常流行&#xff0c;似乎「大语…

使用Three.js开发一个3D案例Demo

使用Three.js开发一个3D案例 最近在找工作&#xff0c;发现好多招聘要求都需要会Three.js&#xff0c;以前接触比较多的是2D开发&#xff0c;也就是平面开发&#xff0c;用到的做多的技术就是d3.js&#xff0c;现在3D开发已经成为了大势所趋&#xff0c;所以就学习下Three.js。…

sql优化思路

sql的优化经验 这里解释一下SQL语句的优化的原理 1.指明字段名称&#xff0c;可以尽量使用覆盖索引&#xff0c;避免回表查询&#xff0c;因此可以提高效率 2.字面意思&#xff0c;无需过多赘述。索引就是为了提高查询效率的。 3.图中两条sql直接可以使用union all 或者 uni…

上市公司财务困境模型​MertonDD、OScore、RLPM、ZScore四种模型​(1992-2022年)

01、数据介绍 上市公司财务困境模型是用于预测和评估上市公司是否可能陷入财务困境的一种模型。这个模型通常基于一系列的财务比率和其他相关变量&#xff0c;通过统计分析方法来构建。​ 数据名称&#xff1a;上市公司财务困境模型MertonDD、OScore、RLPM、ZScore五种模型 …

PHPStudy Apache或者MySQL启动以后自动停止

问题 phpstudy小皮面板中的Apache或MySQL启动以后自动停止 正在启动——已启动——已停止 总结&#xff1a;最主要的原因&#xff1a;端口冲突 端口冲突了&#xff0c;已经有其他程序占用了80、3306端口。 也就是说你的电脑上已经有了一个Apache、MySQL并且正在运行。 解决方案…

springboot lua检查redis库存

需求 最近需求需要实现检查多个马戏场次下的座位等席对应库存渠道的库存余量&#xff0c;考虑到性能&#xff0c;决定采用Lua脚本实现库存检查。 数据结构 库存层级结构 redis库存hash类型结构 实现 lua脚本 --- 字符串分割为数组 local function split(str, char)local…

微信小程序16: 组件通信

父子组件之间的通信 父子组件通信一共有三种方式 属性绑定 用于父组件向子组件的指定属性设置数据&#xff0c;仅能设置JSON兼容的数据 事件绑定 用于子组件向父组件传递数据&#xff0c;可以传递任意数据 获取组件实例 父组件还可以通过this.selectComponent()获取子组件的实…

蓝桥杯单片机之模块代码《AT24C02》

过往历程 历程1&#xff1a;秒表 历程2&#xff1a;按键显示时钟 历程3&#xff1a;列矩阵按键显示时钟 历程4&#xff1a;行矩阵按键显示时钟 历程5&#xff1a;新DS1302 历程6&#xff1a;小数点精确后两位ds18b20 历程7&#xff1a;35定时器测量频率 文章目录 过往历…

吴恩达2022机器学习专项课程C2(高级学习算法)W1(神经网络):2.4 神经网络层

目录 神经网络第一层&#xff08;隐藏层&#xff09;计算过程1.输入向量2.神经元的计算2.标识不同神经元3.层输出&#xff08;激活&#xff09;向量4.神经网络分层5.标识不同层 神经网络第二层&#xff08;输出层&#xff09;计算过程1.输入向量2.层输出&#xff08;激活&#…

cmake进阶:目录属性之 INCLUDE_DIRECTORIES说明二

一. 简介 前面几篇文章学习了 cmake的一些目录属性&#xff0c;主要有两个重要的目录属性INCLUDE_DIRECTORIES 属性、LINK_DIRECTORIES 属性。文章如下&#xff1a; cmake进阶&#xff1a;目录属性之 INCLUDE_DIRECTORIES-CSDN博客 本文学习 父目录的 INCLUDE_DIRECTORIES …

基于svm的手写数字识别程序介绍(matlab)

1、程序界面介绍 该程序GUI界面包括手写板、手写数字可视化&#xff08;原图&#xff09;、对图像进行灰度处理&#xff08;灰度图&#xff09;、图像二值化处理&#xff08;二值化&#xff09;、图像特征可视化&#xff08;HOG特征&#xff08;方向梯度直方图&#xff09;&…

解决Node.js mysql客户端不支持认证协议引发的“ER_NOT_SUPPORTED_AUTH_MODE”问题

这是一个版本问题 我用koa2和mysql2链接就没有问题 不知道这个老项目运行为啥有这个问题 解决方案 打开mysql运行这个两个命令&#xff1a; ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 123321; FLUSH PRIVILEGES; 须知(给小白看的&#xff01;) …