精华内容
下载资源
问答
  • 删除单链表中所有值为x的元素

    万次阅读 2016-04-06 22:19:43
    删除所有值为x的单链表中的元素 首先,我们先考虑第一种情况,就是说值删除第一个值为x的元素,这个比较简单, 只需要挨个比较x和链表节点的值,找到值相同的节点的前一个就可以删除这个节点了。 然后我们可以考虑...

    删除所有值为x的单链表中的元素

    首先,我们先考虑第一种情况,就是说值删除第一个值为x的元素,这个比较简单,

    只需要挨个比较x和链表节点的值,找到值相同的节点的前一个就可以删除这个节点了。

    然后我们可以考虑两种办法第一种就是递归的去删除,这个比较简单,只需要删除第一个值和我们要删除的值一样的节点,然后把下一个节点当做头指针传先去就好了。

    这个就不给与代码了。我把头删的代码也贴上来。

    void DeleteHead( PNODE* phead)
    {
    	if( NULL != *phead )
    	{
    		PNODE pDelete = *phead;
    		*phead = (*phead)->next;
    		delete pDelete;
    		pDelete = nullptr;
    	}
    }

    那么,我们来考虑一下非递归的方法吧。

    PNODE DeleteByValue( PNODE* pHead, int val )
    {
    	PNODE p1,p2;
    	PNODE pos;
    
    	pos = *pHead;
    	while( (*pHead) != NULL && (*pHead)->val == val )
    	{
    		DeleteHead(pHead);
    	}
    
    	if( NULL != *pHead )
    	{
    		p1 = *pHead;
    		p2 = (*pHead)->next;
    		while( p2 != NULL )
    		{
    			while( p2 != NULL && p2->val == val )
    			{
    				p1->next = p2->next;
    				delete p2;
    				p2 = NULL;
    				p2 = p1->next;
    			}
    			if(p2 == NULL )
    			{
    				break;
    			}
    			p1 = p1->next;
    			p2 = p2->next;
    		}
    	}	
    	return *pHead;
    
    }

    作为一个程序员应该是可以看懂这些代码的。首先,我们做了一个判断头结点的值是否和我们要删除的值相等,我们一直删除到第一个节点的值不和我们要删除的节点相等为止。首先,我们判断链表是否还有节点,如果有,我们维护两个指针,一个指向头结点,一个指向第二个节点,首先,这里有一个问题就是第一个指针指向的头结点一定不会被删除,因为前面已经删除了头结点的值一样的情况。所以我们在第二个指针不是空的前提下判断第二个节点的值是否和我们的值一样就可以了。如果,我们的第二个指针和要删除的值一样了那么删除第二个节点。首先,将第一的节点的下一个指向第二个节点的下一个。然后删除第二个节点。接着我们把第二个指针的值赋为第一的next,然后一直删除到第二个节点也不一样为止。这样就删除了一段值和我们要删除的相同的情况了。然后判断第二个指针是不是空了。空了 就退出。不空的后移。

    展开全文
  • 代码有解释,可能一开始看不到,更着动手多敲几遍就能掌握了。加油。题目描述:给定一个带头结点的单链表,请将其逆序。...由于单链表与数组不同, 每个结点地址都存储在其前驱结点指针域...

    b955279743c55d47ba42f9fd9e1d9743.png

    代码有解释,可能一开始看不到,更着动手多敲几遍就能掌握了。加油。

    题目描述:

    给定一个带头结点的单链表,请将其逆序。即如果单链表原来为head->1->2->3->4->5->6->7,那么逆序后变为head->7->6->5->4->3->2->1。

    • 由于单链表与数组不同, 中每个结点的地址都存储在其前驱结点的指针域中, 因此,对单链表中任何 个结点的访问只能从链表的头指针开始进行遍历。在对链表的操作 过程中,需要特别注意在修改结点指针域的时候,记录下后继结点的地址,否 会丢失后继结点。

    先定义好链表结构

    # -*- coding: utf-8 -*-
    

    一、递归逆序

    思路:

    1、首先将1 -> 2 -> 3 ->4变成1 -> 4-> 3 -> 2(其中2 -> 3 ->4变成4-> 3 -> 2,采用递归方式实现)

    2、再将head头节点1移到尾巴,作为尾结点,由于上一个尾结点2,是原先的head.next,此时将2的next指针指向头节点,即head.next.next = head,然后尾结点指向空,即head.next = None

    3248fab86f669f927bfcf216dcac32eb.png

    3、特殊情况:头节点为空或者只有1个节点

    """
    

    算法性能分析:

    由于递归法也只需要对链表进行 次遍历,因此,算法的时间复杂度也为 O(N) ,其中,N为链表的长度。

    • 递归法的主要优点是:思路比较直观,容易理解,而且也不需要保存前驱 结点的地址
    • 缺点是:算法实现的难度较大,此外,由于递归法需要不断地调用自己,需要 额外的压技与弹枝操作,因此, 与方法 相比性能会有所 降。

    二、就地逆序

    d3c7e51c089da113c84176a930b54747.png

    移动:第1次指针操作,将当前节点指针cur.next值临时保存到nex,即nex = cur.next, 第2次指针操作,将当前的指针cur.next指向其前一个节点pre, 即cur.next = pre,这样就实现了对单个节点的操作。

    操作节点的变量移动,pre结点后移:pre_node = cur_node ,cur指向下一个操作节点,即cur = nex,这样通过while循环即可实现对每个节点操作。

    特殊情况:链表为空链表、链表为单节点,直接返回即可,无需逆序操作

    """
    

    三、插入逆序

    直假定原链表为head->1->2->3->4->5->6->7,在遍历到2的时候,将其插入到头结点后,链表变为head->2->1->3->4->5->6->7,同理将后序遍历到的所有结点都插入到头结点head后,就可以实现链表的逆序。实现代码如下:

    """
    

    测试

    # 当然,也许还有别的方法,比如建一个辅助的链表
    

    参考:

    《python程序员宝典》

    展开全文
  • 反转链表II-----------反转单链表迭代实现不是一个困难事情,但是递归实现就有点难度了,如果再加一点难度,让你仅仅反转单链表中的一部分,你是否能够递归实现呢?本文就来由浅入深,step by step 地解决这个...

    读完本文,你可以去力扣拿下如下题目:

    92.反转链表II

    -----------

    反转单链表的迭代实现不是一个困难的事情,但是递归实现就有点难度了,如果再加一点难度,让你仅仅反转单链表中的一部分,你是否能够递归实现呢?

    本文就来由浅入深,step by step 地解决这个问题。如果你还不会递归地反转单链表也没关系,本文会从递归反转整个单链表开始拓展,只要你明白单链表的结构,相信你能够有所收获。

    // 单链表节点的结构
    public class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }
    

    什么叫反转单链表的一部分呢,就是给你一个索引区间,让你把单链表中这部分元素反转,其他部分不变:
    e

    a3a8857cf7eca28a20b012c3230be94f.png

    注意这里的索引是从 1 开始的。迭代的思路大概是:先用一个 for 循环找到第 m 个位置,然后再用一个 for 循环将 mn 之间的元素反转。但是我们的递归解法不用一个 for 循环,纯递归实现反转。

    迭代实现思路看起来虽然简单,但是细节问题很多的,反而不容易写对。相反,递归实现就很简洁优美,下面就由浅入深,先从反转整个单链表说起。

    一、递归反转整个链表

    这个算法可能很多读者都听说过,这里详细介绍一下,先直接看实现代码:

    ListNode reverse(ListNode head) {
        if (head.next == null) return head;
        ListNode last = reverse(head.next);
        head.next.next = head;
        head.next = null;
        return last;
    }
    

    看起来是不是感觉不知所云,完全不能理解这样为什么能够反转链表?这就对了,这个算法常常拿来显示递归的巧妙和优美,我们下面来详细解释一下这段代码。

    对于递归算法,最重要的就是明确递归函数的定义。具体来说,我们的 reverse 函数定义是这样的:

    输入一个节点 head,将「以 head 为起点」的链表反转,并返回反转之后的头结点

    明白了函数的定义,在来看这个问题。比如说我们想反转这个链表:

    9cd12010435968fef7fd1fdf8484afe5.png

    那么输入 reverse(head) 后,会在这里进行递归:

    ListNode last = reverse(head.next);
    

    不要跳进递归(你的脑袋能压几个栈呀?),而是要根据刚才的函数定义,来弄清楚这段代码会产生什么结果:

    c89d9df83566ca5a46a4184d6630b97b.png

    这个 reverse(head.next) 执行完成后,整个链表就成了这样:

    cd679bc6e99cc9cde07492c823c1952a.png

    并且根据函数定义,reverse 函数会返回反转之后的头结点,我们用变量 last 接收了。

    PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

    现在再来看下面的代码:

    head.next.next = head;
    

    5f07b837c8d92f7508c6e0d8dc32aa80.png

    接下来:

    head.next = null;
    return last;
    

    ef92d2a3df477271fa5a6750dedd6b34.png

    神不神奇,这样整个链表就反转过来了!递归代码就是这么简洁优雅,不过其中有两个地方需要注意:

    1、递归函数要有 base case,也就是这句:

    if (head.next == null) return head;
    

    意思是如果链表只有一个节点的时候反转也是它自己,直接返回即可。

    2、当链表递归反转之后,新的头结点是 last,而之前的 head 变成了最后一个节点,别忘了链表的末尾要指向 null:

    head.next = null;
    

    理解了这两点后,我们就可以进一步深入了,接下来的问题其实都是在这个算法上的扩展。

    二、反转链表前 N 个节点

    这次我们实现一个这样的函数:

    // 将链表的前 n 个节点反转(n <= 链表长度)
    ListNode reverseN(ListNode head, int n)
    

    比如说对于下图链表,执行 reverseN(head, 3)

    1fa9aa95945da78788399762bfcf3516.png

    解决思路和反转整个链表差不多,只要稍加修改即可:

    ListNode successor = null; // 后驱节点
    
    // 反转以 head 为起点的 n 个节点,返回新的头结点
    ListNode reverseN(ListNode head, int n) {
        if (n == 1) { 
            // 记录第 n + 1 个节点
            successor = head.next;
            return head;
        }
        // 以 head.next 为起点,需要反转前 n - 1 个节点
        ListNode last = reverseN(head.next, n - 1);
    
        head.next.next = head;
        // 让反转之后的 head 节点和后面的节点连起来
        head.next = successor;
        return last;
    }    
    

    具体的区别:

    1、base case 变为 n == 1,反转一个元素,就是它本身,同时要记录后驱节点

    2、刚才我们直接把 head.next 设置为 null,因为整个链表反转后原来的 head 变成了整个链表的最后一个节点。但现在 head 节点在递归反转之后不一定是最后一个节点了,所以要记录后驱 successor(第 n + 1 个节点),反转之后将 head 连接上。

    60bb0fd3bcebf069b913b8094183b170.png

    OK,如果这个函数你也能看懂,就离实现「反转一部分链表」不远了。

    PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

    三、反转链表的一部分

    现在解决我们最开始提出的问题,给一个索引区间 [m,n](索引从 1 开始),仅仅反转区间中的链表元素。

    ListNode reverseBetween(ListNode head, int m, int n)
    

    首先,如果 m == 1,就相当于反转链表开头的 n 个元素嘛,也就是我们刚才实现的功能:

    ListNode reverseBetween(ListNode head, int m, int n) {
        // base case
        if (m == 1) {
            // 相当于反转前 n 个元素
            return reverseN(head, n);
        }
        // ...
    }
    

    如果 m != 1 怎么办?如果我们把 head 的索引视为 1,那么我们是想从第 m 个元素开始反转对吧;如果把 head.next 的索引视为 1 呢?那么相对于 head.next,反转的区间应该是从第 m - 1 个元素开始的;那么对于 head.next.next 呢……

    区别于迭代思想,这就是递归思想,所以我们可以完成代码:

    ListNode reverseBetween(ListNode head, int m, int n) {
        // base case
        if (m == 1) {
            return reverseN(head, n);
        }
        // 前进到反转的起点触发 base case
        head.next = reverseBetween(head.next, m - 1, n - 1);
        return head;
    }
    

    至此,我们的最终大 BOSS 就被解决了。

    PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在 labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。

    四、最后总结

    递归的思想相对迭代思想,稍微有点难以理解,处理的技巧是:不要跳进递归,而是利用明确的定义来实现算法逻辑。

    处理看起来比较困难的问题,可以尝试化整为零,把一些简单的解法进行修改,解决困难的问题。

    值得一提的是,递归操作链表并不高效。和迭代解法相比,虽然时间复杂度都是 O(N),但是迭代解法的空间复杂度是 O(1),而递归解法需要堆栈,空间复杂度是 O(N)。所以递归操作链表可以作为对递归算法的练习或者拿去和小伙伴装逼,但是考虑效率的话还是使用迭代算法更好。

    _____________

    我的 在线电子书 有 100 篇原创文章,手把手带刷 200 道力扣题目,建议收藏!对应的 GitHub 算法仓库 已经获得了 70k star,欢迎标星!

    展开全文
  • 1. 链表概述还记得在顺序表(数组),我们插入、删除一个元素,都需要移动大量的元素,来达到顺序排列的目的,所以计算量较大,是否有一种不需要移动元素即能插入或者删除元素的线性表结构呢,答案是有的,那就是...

    经过了上篇顺序表的学习,我们大概清楚了顺序表的特性,这篇我们来学习线性表的另一种结构:链表。

    1. 链表概述

    还记得在顺序表(数组)中,我们插入、删除一个元素,都需要移动大量的元素,来达到顺序排列的目的,所以计算量较大,是否有一种不需要移动元素即能插入或者删除元素的线性表结构呢,答案是有的,那就是链表结构。

    链表分为:单链表、循环链表、双向链表、静态链表等。我们先看单链表,结构大致如下图所示。一个链表结点包含有数据域和指针域两部分,前一个结点的指针域存有下一个结点的指针地址,所以就形成了链式数据结构,而最后一个结点的指针域是指向NULL的。注意:一般链表头部都会有一个结点,它不包含数据域,只有指向第一个结点的指针,这个结点叫做头结点,指针叫做头指针。

    36c880da5b524a28069d2d71e74e7e0e.png

    所以链表的插入和删除是不需要移动元素的,只需要将插入位置的前一个结点的指针指向插入结点,插入结点的指针指向插入位置的下一个结点,说起来很拗口,其实理解起来并不费劲。插入过程如下图所示。

    1686da97e203ecb46337b531fb52a07c.png

    删除也同理,只需将删除结点的前一个结点直接指向下一个结点即可,然后释放删除结点的内存。过程如下图所示。

    16f63845035e09eff29b1a6344ca5e60.png

    2. 实现单链表

    我们依次来实现单链表的插入、删除、清空。

    我们还是沿用顺序表的数据元素ElementType结构体。

    typedef struct {
        int id;
        char* name;
    }ElementType;

    接着定义单链表的“结点”,结点包含一个数据域和一个指针域。

    /**定义链表的结点,包含数据域和指针域*/
    typedef struct Node {
        ElementType date;   ///数据域
        struct Node* next;  ///指针域
    }Node;

    然后定义头结点,包含一个头指针和链表的元素个数(length)。可以看到我们将头结点就命名为LinkList,是因为单链表的初始化都是从头结点开始,然后根据指针一个一个地遍历下去的。

    /**头结点*/
    typedef struct LinkList {
        Node* next; ///头指针(如果链表有头结点,next就指向头结点,没有就指向第一个结点)
        int length; ///链表的长度,初始值为0
    }LinkList;

    然后我们开始实现插入。插入位置分第一个结点位置、中间位置、尾结点位置。第一个结点不需要遍历链表,直接头结点指向即可。如果插入的不是第一个结点位置,那我们必须遍历链表,找到插入位置的前后结点,然后插入结点,重新设置前后结点的指针域。最后一个结点位置,将插入结点的指针域置为空即可。记得插入后链表长度加一。

    /**在指定位置pos处,插入元素element*/
    void InsertLinkList(LinkList* linklist, int pos, ElementType element)
    {
        ///1、创建空结点并为数据域赋值
        Node* node = (Node*)malloc(sizeof(Node));
        node->date = element;
        node->next = NULL;
    
        ///2、找到要插入位置的结点
        if (pos == 1)///如果插入的是第一个元素
        {
            linklist->next = node;
            linklist->length++;
            return;
        }
        ///通过循环找到要插入的结点位置
        Node* currNode = linklist->next;///第一个结点
        for (int i = 1; currNode && i < pos - 1; i++)
        {
            ///将下一个结点的地址赋值给当前结点(相当于移动到下一个结点)
            currNode = currNode->next;
        }
    
        ///3、将结点插入并对接前面的结点
        if (currNode)
        {
            ///必须先后再前,不然currNode->next值被改了
            node->next = currNode->next;///node和后面结点对接
            currNode->next = node;///node和前面结点对接
            linklist->length++;
        }
    }

    接着实现下删除操作,也同样分删除的是第一个结点位置、中间结点位置、尾结点位置,删除结点后,重新设置前后结点的指针,最后链表长度减一。注意:必须释放删除结点内存。

    ElementType DeleteLinkListElement(LinkList* linkList, int pos)
    {
        Node* node = linkList->next;//初始化第一个结点(头结点指向第一个结点)
        Node* prevNode = NULL;//删除结点的前一个结点
        ElementType delElement = {};//初始化删除结点数据
    
        //删除结点超出范围
        if (pos > linkList->length)
        {
            printf("超出数组范围n");
            return delElement;
        }
        //删除第一个结点
        if (pos == 1)
        {
            if (node)
            {
                linkList->next = node->next;//头结点指向第二个结点
                delElement = node->date;//保存删除结点的数据
                free(node);//删除结点,释放内存
                linkList->length--;     //链表长度减一      
            } 
            return delElement;
        }
    
        //删除除第一个以外的结点
        //循环遍历到要删除的元素处
        for (int i = 1; node && i < pos; i++)
        {
            prevNode = node;//记录上一个结点
            node = node->next;
        }
    
        //删除元素并返回
        if (node)
        {
            prevNode->next = node->next;//前一个结点指向删除结点的下一个结点
            delElement = node->date;//保存删除结点的数据
            free(node);//删除结点,释放内存
            linkList->length--;//链表长度减一
    
            return delElement;
        }
        
    }

    最后实现清空链表。我们使用循环,按指针顺序一个一个的遍历并删除结点,最终删完所有结点,并将链表长度清零,头指针置为空。

    /*清空链表*/
    void ClearLinkList(LinkList* linkList)
    {
        Node* node = linkList->next;//头指针指向第一个结点
        Node* nextNode = NULL;
        while (node)
        {
            nextNode = node->next;
            free(node);
            node = nextNode;
        }
        linkList->length = 0;
        linkList->next = NULL;
    }

    然后我们实现初始化函数,将结点挨个插入。

    /**初始化链表*/
    void InitLinkList(LinkList* linklist, ElementType* dataArray, int length)
    {
        for (int i = 0; i < length; i++)
        {
            InsertLinkList(linklist, i + 1, dataArray[i]);
        }
    }

    最后为了测试,我们再实现一个遍历链表并打印的函数。链表的遍历:node = node->next;这是链表遍历中最常用到的代码,这在插入和删除函数中遍历链表时也同样用到。

    void PrintLinkList(LinkList* linklist)
    {
        Node* node = linklist->next;
        if (!node)
        {
            printf("LinkList is null!n");
            linklist->length = 0;
            return;
        }
        for (int i = 1; i <= linklist->length; i++)
        {
            printf("%dt%sn", node->date.id, node->date.name);
            node = node->next;
        }
    }

    我们开始测试,在主函数中执行链表测试函数。链表测试函数如下,首先初始化链表,然后删除3号结点,最后清空链表。

    void TestLinkList()
    {
        LinkList linklist;
        linklist.length = 0;
        InitLinkList(&linklist, dataArray, sizeof(dataArray) / sizeof(dataArray[0]));
        printf("初始化列表:n");
        PrintLinkList(&linklist);
        printf("删除后的列表:n");
        ElementType delData = DeleteLinkListElement(&linklist, 3);
        PrintLinkList(&linklist); 
        printf("删除的是:n%dt%sn", delData.id, delData.name); 
        ClearLinkList(&linklist);
        printf("链表清空后n");
        PrintLinkList(&linklist);
    }

    编译运行,3号结点“山治”被删除了,清空链表后,打出了“LinkList is null!”的字符串。链表插入、删除、清空成功。

    625a3f420affc8685b62bf52a5079bca.png

    3. 单链表总结

    我们简单地对单链表结构和顺序表结构做对比:

    存储分配方式:(1)顺序表结构用一段连续地存储单元依次存储线性表的数据元素。

    (2)单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。

    时间性能:(1)顺序表查找直接使用下标,速度非常快,时间为0[1]。插入和删除需要平均移动表长一半的元素,时间为0[n]。

    (2)单链表查找需要根据指针从头遍历,速度比顺序表慢(根据遍历的次数)时间为n[n]。链表插入和删除时,遍历出插入或删除位置的前后结点,再设置他们的指针,而不需要移动元素,所以时间为0[1]。

    空间性能:(1)顺序表结构需要预分配存储空间,分大了,浪费,分小了,容易溢出。

    (2)单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。

    所以我们总结:如果线性表需要频繁查找,很少进行插入和删除操作时,我们宜采用顺序表存储结构。如果需要频繁插入和删除时,宜采用单链表结构。当线性表中元素个数变化较大或者根本不知道有多大时,宜采用单链表结构。如果事先知道线性表的大致长度,宜采用顺序表结构。

    展开全文
  • 链表第一个结点地址可通过头指针找到,其他结点地址则在前驱结点指针域,最后一个结点没有后继,用NULL终结。为了操作方便,习惯上单链表带一个头结点,也就是first指向第一个结点不...
  • 「线性表」是元素的集合并且记录着元素之间一种顺序关系,是最基本的...「顺序表」是将表中的元素顺序存放在一大块连续的存储区间里,所以在这里元素间的顺序是由它们的存储顺序来表示的。「链表」则是将表元素...
  • 单链表属于线性表的范畴,线性表就是这样一组元素的抽象,它是某类元素的集合并且记录着元素之间一种顺序关系,是最基本的...「顺序表」是将表中的元素顺序存放在一大块连续的存储区间里,所以在这里元素间的顺序...
  • 里面有详细讲解,编程小白也能轻松看懂哦
  • 将带头结点的单链表A分解成两个带头结点的单链表A和B,使得A表含有原表序号奇数的元素,B表含有原表序号偶数的元素,且保持相对顺序不变LinkList 将C={a1,b1,a2,b2…an,bn}线性表采用带头结点的单链表...
  • 双链表双链表意义单链表相对于顺序表,确实在某些场景下解决了一些重要问题,例如在需要插入或者删除大量元素的时候,它并不需要像顺序表一样移动很多元素,只需要修改指针指向就可以了,其时间复杂度 O(1) ...
  • L,int x){//用尾插法建立一个新的单链表,将为x的元素链接到表尾 LNode *p=L->next,*r=L,*q;//假设单链表带头结点,p指针用来扫描整个链表,r指针初值为头结点,之后始终指向表尾 while(p){ if(p->...
  • 第一次学习线性表一定会马上接触到一种叫做顺序表(顺序存储结构),经过上一篇的分析顺序表的优缺点是很显然的,它虽然能够很快的访问读取元素,但是在解决如插入和删除等操作的时候,却需要移动大量的元素,效率较低...
  • 一个节点表示链表中的一个数据元素,除了包括存储数据信息外,还需要包含下一个节点指向信息,所以一个节点会包含数据域和指针域,数据域存储元素的数据信息,指针域指示直接后继信息。如下图...
  • 在已有的单链表中删除所有值为x的元素,代码如下: class Node(object): # 初始化结点 def __init__(self,num): self.num=num self.next=None class SingleLinkedList(object): # 初始化头结点 def __init__...
  • #include typedef struct node{ int data; struct node *next; }list,*nlist; nlist create() { nlist head=(nlist)malloc(sizeof(list)), end; // new =(nlist)malloc(sizeof(list)) ...int x=0; if
  • /*设计一个递归算法,删除带头结点的单链表L中所有值为x的结点*/ #include <stdio.h> #include <stdlib.h> typedef struct Link{ int data;//代表数据域 struct Link* next;// 代表指针域,指向直接...
  • typedef int type; typedef struct ...void reverse(sqList *a,int m,int n)//把数组中的元素从下标n到 下标n的元素逆置 { for(int i=0;i&amp;lt;=(n-m)/2;i++) { int t; ...
  • 既然是递归,我们就要考虑,递归基是什么,很明显,这一题递归基也就是当指向元素的指针,指向NULL时候,我们就直接返回头节点即可 这道题我是这么一个思路,然后让人棘手就是,在递归时候如何进行删除?...
  • 写一算法,删除线性表中所有值小于x的元素。 输入格式 第一行 输入表长 第二行 输入指定表长的整数 第三行 输入一个整数 输出格式 第一行 表中的数据 第二行 处理后的表中的数据 输入样例 8 5 3 4 9 8 7 6 2 5 输出...
  • 单链表的删除

    千次阅读 2019-03-01 14:56:40
    建立一个长度为n的单链表,删除链表中所有数据元素为x的结点。(数据类型为整型) 输入 第一行为链表的长度n; 第二行为链表中的数据元素; 第三行为要删除的数据元素x的。 输出 删除数据x后,单链表中的数据元素。 ...
  • 问题描述:给定一个单链表,链表中存储的数据都整数,给定一个整数x,将单链表中所有x相等的元素删除。 例如:单链表(1,2,3,4,2,4),x=2,则删除节点后链表(1,3,4,4) 分析:这是链表的基本...
  • 这里要删除顺序表的所有值为x的结点,跟单链表那题题意相同。 主要区别就是:存储结构不同 这里是顺序存储结构 单链表是链式存储结构 所以解题方法也跟链表的不一样。 这里采用:相等加一,不等前移k 我们用k记录下...
  • 这里要删除顺序表的所有值为x的结点,跟单链表那题题意类似。 主要区别就是:存储结构不同 这里是顺序存储结构 单链表是链式存储结构 所以解题方法也跟链表的不一样。 这里 :另建表存放不同+复制到原表 我们另建一...
  • 对值递增有序的单链表进行以下操作:若表存在值为x的结点,则将它从表中删除;否则,就往表插入一个值为x的结点,并保持表值递增有序的性质不变(假设表没有值相同的元素)。处理后若为空表则不输出。   ...
  • 这里要删除顺序表的所有值为x的结点,跟单链表那题题意相同。 主要区别就是:存储结构不同 这里是顺序存储结构 单链表是链式存储结构 所以解题方法也跟链表的不一样。 这里我们采用遍历顺序表L,来新建一个顺序表 ...
  • 题目:在带头结点的单链表L删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现上述操作。 关键字:带头结点单链表L,按值删除,释放空间 思路 关注:递归算法的设计重点在于找到...
  • 题目:设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点。 关键字:递归算法+不带头结点的单链表+按值删除 思路 关注:递归算法的设计重点在于找到“递归”的部分,即重复调用函数,改变部分相关变量 设...

空空如也

空空如也

1 2 3 4 5
收藏数 84
精华内容 33
关键字:

删除单链表中所有值为x的元素