精华内容
下载资源
问答
  • 最近在复习时候,发现网上资料都只告诉了怎么做,但是根本没有好好介绍两种方法实现过程与原理。所以我觉得有必要好好整理一篇博文,来帮忙大家一步步理解其中实现细节。 我们知道迭代是从前往后依次处理...
    • 链表的翻转是程序员面试中出现频度最高的问题之一,常见的解决方法分为递归和迭代两种。最近在复习的时候,发现网上的资料都只告诉了怎么做,但是根本没有好好介绍两种方法的实现过程与原理。所以我觉得有必要好好的整理一篇博文,来帮忙大家一步步理解其中的实现细节。 
    • 我们知道迭代是从前往后依次处理,直到循环到链尾;而递归恰恰相反,首先一直迭代到链尾也就是递归基判断的准则,然后再逐层返回处理到开头。总结来说,链表翻转操作的顺序对于迭代来说是从链头往链尾,而对于递归是从链尾往链头。下面我会用详细的图文来剖析其中实现的细节。 

    1.非递归(迭代)方式 

    • 迭代的方式是从链头开始处理,如下图给定一个存放5个数的链表。

    • 首先对于链表设置两个指针:

    • 然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示。此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针tmp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=tmp就可以取回原链表的数据了,所有循环访问也可以继续展开下去。

    • 指针继续向后移动,直到P指针指向NULL停止迭代。

    • 最后一步:

    • 非递归实现的程序
    struct ListNode* reverseList(struct ListNode* head)
    {
        if (head == NULL || head->next == NULL) //链表为空或者仅1个数直接返回
            return head;
        
        struct ListNode* p,*newH;
        p=head;
        newH=NULL;
        
        while (p)                
        {
            struct ListNode* q;
            q= p->next;          
            p->next = newH;               
            newH = p;                    
            p = q;                   
        }
        
        return newH;
    }

    2.递归方式 

    • 我们再来看看递归实现链表翻转的实现,前面非递归方式是从前面数1开始往后依次处理,而递归方式则恰恰相反,它先循环找到最后面指向的数5,然后从5开始处理依次翻转整个链表。 
    • 首先指针H迭代到底如下图所示,并且设置一个新的指针作为翻转后的链表的头。由于整个链表翻转之后的头就是最后一个数,所以整个过程NewH指针一直指向存放5的地址空间。

    • 然后H指针逐层返回的时候依次做下图的处理,将H指向的地址赋值给H->next->next指针,并且一定要记得让H->next =NULL,也就是断开现在指针的链接,否则新的链表形成了环,下一层H->next->next赋值的时候会覆盖后续的值。

    • 继续返回操作:

    • 上图第一次如果没有将存放4空间的next指针赋值指向NULL,第二次H->next->next=H,就会将存放5的地址空间覆盖为3,这样链表一切都大乱了。接着逐层返回下去,直到对存放1的地址空间处理。

    • 返回到头:

    • 递归实现程序
    struct ListNode* reverseList(struct ListNode* head)
    {
        if (head == NULL || head->next == NULL)      
            return head;
        
        struct ListNode* newHead = reverseList(head->next); 
        head->next->next = head;                      
        head->next = NULL;                         
        
        return newHead;                          
    }

    3.带头结点链表的反转

    • 题目描述:/* 设计一个算法,通过一趟遍历,将链表中所有的链接方向反转,仍利用原表的空间 */
    • 思想:先将链表的头结点指针域置空,p指向链表的第一个结点;q指向*p的后继,然后将*p插入到头结点的后面。
    void TurnList(LinkList &L) 
    {
    	struct LNode *p;
    	p = L->next;
    	L->next = NULL;
    	while (p) 
    	{
    		LNode *q;
    		q = p->next;     //   q指向*p的后继 
    		p->next = L->next;
    		L->next = p;    // 将*p插入到头结点之后 
    		p = q;
    	}
    }
    • 代码实现
    • main.cpp
    #include<iostream>
    
    using namespace std;
    
    typedef struct LNode 
    {
    	int data;
    	struct LNode *next;
    }LNode, *LinkList;
    
    int InitList(LinkList &L) 
    {
    	L = new LNode;
    	L->next = NULL;
    	return 1;
    }
    
    void TraveList(LinkList L)
    {
    	LNode *p;
    	p = L->next;
    	
    	printf("遍历链表:\n");
    	while (p) 
    	{
    		printf("%d ", p->data);
    		p = p->next;
    	}
    	printf("\n");
    }
    
    //前插法创建单链表 
    void CreateList(LinkList &L, int n) 
    {
    	L = new LNode;
    	L->next = NULL;
    	for (int i = n; i > 0; --i) 
    	{
    		printf("请输入第%d个元素的值:", i);
    		struct LNode *p;
    		p = new LNode;
    		scanf("%d", &p->data);
    		p->next = L->next;
    		L->next = p;
    	}
    }
    
    /*
    思想:
    先将链表的头结点指针域置空,p指向链表的第一个结点;
    q指向*p的后继,然后将*p插入到头结点的后面。
    */
    void TurnList(LinkList &L) 
    {
    	struct LNode *p;
    	p = L->next;
    	L->next = NULL;
    	while (p) 
    	{
    		LNode *q;
    		q = p->next;     //   q指向*p的后继 
    		p->next = L->next;
    		L->next = p;    // 将*p插入到头结点之后 
    		p = q;
    	}
    }
    
    int main() 
    {
    	LinkList L;
    
    	if (InitList(L)) 
    	{
    		printf("链表初始化成功!\n");
    	}
    	else 
    	{
    		printf("链表初始化失败!\n");
    	}
    
    	printf("请输入链表的长度:\n");
    	int n;
    	scanf("%d", &n);
    	CreateList(L, n);
    	TraveList(L);
    
    	printf("反转后的链表:\n");
    	TurnList(L);
    	TraveList(L);
    
    	system("pause");
    
    	return 0;
    }
    • 运行结果

    展开全文
  • 咱们老套路先上图:下面是我通过遍历拿到所有id,怎么做的呢? 咱们先说下思路: 首先拿到最外层ViewGroup然后通过它拿到它所有child然后循环每个child判断是ViewGroup还是View,如果是ViewGroup就继续...

    面试题如题:

    咱们老套路先上图:下面是我通过遍历拿到的所有的id,怎么做的呢?

    咱们先说下思路:

    首先拿到最外层的ViewGroup然后通过它拿到它所有的child然后循环每个child判断是ViewGroup还是View,如果是ViewGroup就继续遍历(递归),不是VieGroup的话那就是View了,那就直接打印View的id即可。

    看代码吧。

     //遍历树形结构view
            ViewGroup llRoot = findViewById(R.id.ll_root);
            forData(llRoot);
       
    
    /**
         * 遍历ViewGroup的方法
         *
         * @param llRoot 根VieGroup
         */
        private void forData(ViewGroup llRoot) {
            int childCount = llRoot.getChildCount();
            for (int i = 0; i < childCount; i++) {
                if (llRoot.getChildAt(i) instanceof ViewGroup) {
                    Log.e("打印ViewGroup的id", llRoot.getChildAt(i).getId() + "=");
                    forData((ViewGroup) llRoot.getChildAt(i));
                } else {
                    Log.e("打印View的id", llRoot.getChildAt(i).getId() + "=");
                }
            }
        }

    咱们再看下xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/ll_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <EditText
            android:id="@+id/et_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:inputType="text"
            android:text="408" />
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="showResult"
            android:text="通过MVP模式显示结果" />
    
        <LinearLayout
            android:id="@+id/ll_two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <LinearLayout
                android:id="@+id/tw_three"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <TextView
                    android:id="@+id/tv_one"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
    
                <TextView
                    android:id="@+id/tv_two"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
    
            <TextView
                android:id="@+id/tv_three"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    
        <ScrollView
            android:id="@+id/sv_four"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/tv_shoe_result"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@android:color/black" />
    
        </ScrollView>
    
    </LinearLayout>

    懂了吧。

    展开全文
  • 这是我初学c开始有意识记录自己做的每一道开始写下代码水平 一个一个代码发出来 直到我现在学数据结构 那个时候还不会注释 格式什么也是按照自己怎么喜欢怎么来 如果真不会看会代码理解一下 qwq 如代码有...

    Mooc课后习题集 及 做到的一些有趣的题

    这是我初学c开始有意识的记录自己做的每一道题开始写下的代码水平 一个一个代码发出来 直到我现在学的数据结构 那个时候还不会注释 格式什么的也是按照自己怎么喜欢怎么来 如果真不会看会代码理解一下 qwq 如代码有错请见谅 毕竟都好久以前敲得了hhh ~~
    如果对各位的思路引导有帮助那更好

    #include <stdio.h>
    
    int main()
    {
        int temp;
        int sum=0,count=0;
        printf("its a little programe to sum up int >0\n");
        do
        {
            printf("Input a number:\n");
            scanf(" %d",&temp);
            if(temp>0)
            {
                sum+=temp;
                count++;
            }
        }while(temp!=0);
        printf("thats the total sum %d\n",sum);
        return 0;
    }
    
    展开全文
  • 今天给大家开始介绍前端方面的数据结构,刚把vue源码过完就开始数据结构...二是当你写逻辑方面代码时候,明明可以一层for循环搞定,非要三层for循环,这里就凸显巧用数据结构的好处了。闲话不多说,直接上来二分搜索...

    deb6e37b8cf0af7a67daed61aaf05511.png

    今天给大家开始介绍前端方面的数据结构,刚把vue源码过完就开始数据结构,可见它的地位有多重要。有人说我一前端又不是后端学这个数据结构干嘛,好吧,只能说你还没有这个意识,一是面试很多大厂就会考察,我面试别人也会出一些简单算法题来做,以此考察逻辑能力以及js基础能力。二是当你写逻辑方面代码时候,明明可以一层for循环搞定,非要三层for循环,这里就凸显巧用数据结构的好处了。闲话不多说,直接上来二分搜索。

    一 二分搜索

    所谓二分查找,就是在有序表中,每次都让被查找数据与当前表的中间结点进行比较,根据比较结果“舍弃”掉以中间结点划分的某一半子表。

    总结出来它的基本逻辑: 优先和数组的中间元素比较,如果等于中间元素,则直接返回。如果不等于则取半继续查找。

    适用场景:假设现在有一个数组,数组中的数据按照某个关键字排好了序,现在我们希望判断某个数据是否已存在于数组中,怎么样做才更快?

    总结出来它的适应场景: 数组 有序

    基本二分查找有 非递归版本 和 递归版本

    397251f67083e9a7c2b0d42b208573ad.png
    非递归版本

    8ccbbe5fc3771582fead067e593ea8d0.png
    递归版本

    由上的方法我们可以总结出二分查找的几个特点:

    1 每次我们都将表的大小减半,也就是除以二 ;

    2 最坏情况下我们要一直“除以2”直到表只剩下一个元素;

    3 二分查找花费的时间关键点就是比较了多少次,而比较的次数在最坏情况下就是表的大小n不断除以2直至n为1的次数。这样以来我们很快就能得出二分查找的时间复杂度:O(log2N) ;

    那如果我们想要表的大小能够动态的变化,并且数据具有层级用什么来表示呢?没错,二叉树。

    222b745a26e1f7e5d7b9bfc9a5238dec.png

    在树结构中,每一个结点只有一个前件,称为父结点,没有前件的结点只有一个,称为树的根结点,简称树的(root)。每一个结点可以有多个后件,称为该结点的子结点。没有后件的结点称为叶子结点。一个结点所拥有的子结点的个数称为该结点的度,所有结点中最大的度称为树的度。树的最大层次称为树的深度。

    同时,我们还可以看到一些基本的树的特点:

    每个节点的键值大于左孩子,每个节点的键值大于右孩子。以左右孩子为根的子树仍然为二分搜索树。

    35b7d422c77be8a33e502b5bcaf133a2.png


    二叉树是一种特殊的树,它的子节点个数不超过两个,且分别称为该结点的左子树(left subtree)与右子树(right subtree),二叉树常被用作二叉查找树和二叉堆或是二叉排序树(BST)。

    二 二叉树的插入

    那么现在我们就用javascript来时实现一个简单的二叉搜索树。

    首先我们创建一个Node类,用于存放树的节点。首先要添加新的节点,首先需要创建一个Node对象,将数据传入该对象。
    其次要检查当前的BST树是否有根节点,如果没有,那么表示是一棵新数,该节点就为该树的根节点,那么插入这个过程就结束了;否则,就要继续进行下一步了。
    如果待插入节点不是根节点,那么就必须对BST进行遍历,找到合适的位置。该过程类似遍历链表,用一个变量存储当前节点,一层一层遍历BST,算法如下:

    1. 设值当前节点为根节点
    2. 如果待插入节点保存的数据小于当前节点,则新节点为原节点的左节点,反之,执行第4步
    3. 如果当前节点的左节点为null,就将新节点放到这个位置,退出循环;反之,继续执行下一次循环
    4. 设置新节点为原节点的右节点
    5. 如果当前节点的右节点为null,就将新节点放到这个位置,退出循环;反之,继续执行下一次循环

    这样,就能保证每次添加的新节点能够放到正确的位置上.

    c0e6184d7f23f801d52b4e92bcae7004.png
    三 二插树的查找

    查找通常分为三种情况 查找最小值 查找最大值 查找定值

    1 查找定值:

    f36ae6f3491318c680717ac871a57483.png

    如果找到就返回该值,未找到就返回null;

    2 查找最小值

    fbade827a929e9b74f74306fc1fe6631.png

    3 查找最大值

    9d081ebb7598f18b201e799a55e43a2a.png

    三 二叉树 的循环遍历

    循环遍历分为 前序遍历 中序遍历 后序遍历

    我们首先构造一个树

    f625ec956957550af94fad38370a179a.png

    52407fd76a3ca5c6b86b89434d409c52.png

    1 前序遍历

    714eebb2c5e66b27c2dd757d021d7c9c.png

    8b58b9bd9f45fcb33f132f171909e616.png

    2 中序遍历

    c34e2bd5e880dcc6ba91f9c58efe0991.png

    3 后序遍历

    550df777a94d5f93311c7924221191e4.png

    4 广度优先遍历

    60e62222a156957e7652d0e4587cb728.png

    四 二叉树 删除节点

    删除节点的思路大致如下:

    首先判断当前节点是否包含待删除的数据,如果包含,则删除该节点;如果不包含,则比较当前节点上的数据和待删除树的的大小关系。如果待删除的数据小于当前节点的数据,则移至当前节点的左子节点继续比较;如果大于,则移至当前节点的右子节点继续比较。
    如果待删除节点是叶子节点(没有子节点),那么只需要将从父节点指向它的链接指向变为null;
    如果待删除节点含有一个子节点,那么原本指向它的节点需要做调整,使其指向它的子节点;
    最后,如果待删除节点包含两个子节点,可以选择查找待删除节点左子树上的最大值或者查找其右子树上的最小值,这里我们选择后一种。

    f20b1ef84970690d0705ca11517ae70d.png

    83f927f5cd9f4745e1cdd2e2fa206568.png

    至此,我们基本操作方法已经分析完了,快来动手实践下吧。

    展开全文
  • java面试典 java 面试 经典

    热门讨论 2010-06-18 13:42:36
    5. 给出两个检查表结构的方法 31 6. 怎样查看数据库引擎的报错 31 7. 比较truncate和delete 命令 31 8. 使用索引的理由 31 9. 给出在STAR SCHEMA中的两种表及它们分别含有的数据 31 10. FACT Table上需要建立何种...
  • Handler机制是面试官非常喜欢问知识点,有关Handler面试也是五花八门,举几个例子: Looperloop()方法中死循环为什么不会造成ANR?死循环会造成cpu资源浪费吗?一个线程中Handler、Looper、MessageQueue...
  • 剑指offer--面试20

    2013-08-13 22:02:00
    做题心得:该本质上并未考查复杂数据结构及算法,而是考查了快速找规律能力!!!  要想作出此,必须先有绝对清晰思路,否则越写越乱(因为涉及到很多的循环打印) 自己当时思路基本符合作者提供...
  • 本章主要学习了栈和队列相关知识,包括顺序栈和链栈出、入栈算法,循环队列... 在作业时候,实践和作业都不知道怎么才能很好地运用栈和队列来解决,特别是作业,不知道如何用队列相关算法写程序;...
  • 24.触发器怎么工作? 答:触发器主要是通过事件进行触发而被执行,当对某一表进行诸如UPDATE、 INSERT 、 DELETE 这些操作时,数据库就会自动执行触发器所定义SQL 语句,从而确保对数 据处理必须符合由这些...
  • java 面试 总结

    2009-09-16 08:45:34
    finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep()...
  • RCP法与RSP法主要区别是前者采用循环渐进开发方式,原型将成为最终产品,而后者将被废弃。(√) 三、简答 1. 软件产品特性是什么? 答: ● 软件是一种逻辑产品,具有无形性;  ● 软件产品生产...
  • 1.如何实现自己有界队列(类似题目还有顺序打印A,B,C三个线程 循环打印,这里就不重复了,原理一样) 2.ZooKeeper和Eureka作为注册中心有什么异同点 3.HashMap底层数据结构?能说说hashCode和equals作用?能说说...
  • 12.4 类层次结构的设计 280 12.4.1 一个传统的层次结构 280 12.4.2 抽象类 283 12.4.3 其他实现方式 285 12.4.4 对象创建的局部化 287 12.5 类层次结构和抽象类 289 12.6 忠告 289 12.7 练习 289 第13章 ...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 121
精华内容 48
热门标签
关键字:

循环结构的题怎么做