【数据结构】第二章小结

ps:第一次用博客园写,记录第一次

一、数据结构第二章主要为:顺序表和链表的构造及其增删查改的一些基本操作,以及粗略计算它们的时间or空间的复杂度。

      1、顺序表:

                         (1)  特点:逻辑结构上相邻,物理存储上也是相邻的,属于随机存储;

                         (2)  优点:便于使用下标进行查找,例如:查找某数组的第6项的数据是几;

                                               存储密度为1;

                         (3)    缺点:由于其物理存储相邻,故无法将空间中零零散散的碎片空间利用起来;

        2、链表:

                         (1)   特点:逻辑结构上相邻,物理存储上不一定相邻的,属于顺序存储;

                                                单链表有头指针指向;

                                                含头结点的空表:L->next=NULL//(头结点的指针域为空)

                                                无头结点的空表:L==NULL//(L为单链表的头指针)

                         (2)    优点:可以充分利用碎片空间;

                                                   可以便于增删--改变指针的指向;

                         (3)    缺点:存储密度小于1;

                                                 需要为指针腾出空间;

         3、链表vs顺序表:

                          (1)在增删工作为主的问题中,主要使用链表,时间复杂度较低;

                          (2)在查询工作中,且使用下标查询为主的问题中,使用顺序表为好;

                          (3)时间复杂度:

                                                        顺序表:

                                                                   取值算法:O(1) 、 查找算法:O(n)、增加or删除算法:O(n)

                                                                   空间复杂度S(n)=O(1)    均没有占用辅助空间;

                                                        链表:

                                                                   取值算法:O(n)、查找算法:O(n)、增加or删除算法:O(n)

                                                                   空间复杂度S(n)=O(1)    均没有占用辅助空间;

二、做题过程中遇到的其他问题

1、心理上:上个学期c++打题过少,对于使用一些函数,指针类型的代码充满恐惧与抗拒,甚至于数组都有那么一点

2、现实中:书本给的代码不够详细,得自己上网搜代码

3、题目上:【1】new运算符的应用:

                    (1)、开辟单变量地址空间

                    指针在初始化时需要动态申请空间 int*a=new int [空间大小] 等同于int*a; a = new int [空间大小],

                   例如:int *a = new int(5) 作用同上,但是同时将整数赋值为5;

                    (2)、开辟数组空间

                   要访问new所开辟的结构体空间,无法直接通过变量名进行,只能通过赋值的指针进行访问。

                    (3)、C++中使用new的注意事项:

                       1、、用户是无法主动调用构造函数的,所以需要借助placement new,但是用户可以主动调用析构函数,所以用完这些对象后,调用析构函数,然后用对应分配内存的方法去释放内存。

                       2、、事实上malloc并不一定比operatornew节省多少时间,用placement new常常是为了考虑性能,所以会配合内存池一起使用。 (ps: 内存池(Memory Pool)是一种内存分配方式。通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。)

                       补充:malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。

                         3、、new与malloc、operator new、placement new 的区别:

                                从本质上来说,malloc(Linux上具体实现可以参考man malloc,glibc通过brk()&mmap()实现)是libc里面实现的一个函数,如果在source code中没有直接或者间接include过stdlib.h,那么gcc就会报出error:‘malloc’ was not declared in this scope。如果生成了目标文件(假定动态链接malloc),如果运行平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或者libc中没有malloc函数,那么会在运行时(Run-time)出错。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就可以把new编译成目标代码(g++4.6.3会向目标中插入_Znwm这个函数,另外,编译器还会根据参数的类型,插入相应的构造函数)。

                             在使用上,malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。第一、malloc 函数返回的是 void * 类型。第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。

                             .......

                         (此后省略,直接放网址,因为发现越查越深入,待以后化成自己知识的时候再写几篇关于这些函数不同的博客)

                     参考资料来源:https://zhidao.baidu.com/question/393285989.html(new的运算符的作用)

                                             https://baike.baidu.com/item/%E5%86%85%E5%AD%98%E6%B1%A0/8577153?fr=aladdin(内存池)

                                             https://baike.baidu.com/item/malloc%E5%87%BD%E6%95%B0/8582146?fr=aladdin(malloc函数(含有其与new的区别))

                                             https://blog.csdn.net/caimagic/article/details/51493741(operator new与new的区别)

                                             https://blog.csdn.net/songchuwang1868/article/details/81353577(较为简单的解释了一下其区别:new、operator new、::new、placement new)

                        

                     【2】关于sort函数的应用及其compare函数的机制:

                                1、、sort的定义:用于C++中,对给定区间所有元素进行排序。头文件是#include <algorithm>

                                2、、

                                       Sort函数包含在头文件为#include<algorithm>的c++标准库中
                                      Sort函数有三个参数:
                                   (1)第一个是要排序的数组的起始地址。
                                   (2)第二个是结束的地址(最后一位要排序的地址的下一地址)
                                   (3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
                                              ps:如果要改变排序方法:需要加入一个比较函数compare(),如:
                          bool  compare( int  a, int  b)
                               {
                                  return  a>b;
                                }
 
                                   参考资料:https://baike.baidu.com/item/sort%E5%87%BD%E6%95%B0/11042699?fr=aladdin

                                                     https://www.cnblogs.com/argenbarbie/p/5266603.html    

三、接下来

当然是好好的打代码,与同学多多交流

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


【啊哈!算法】算法3:最常用的排序——快速排序       上一节的冒泡排序可以说是我们学习第一个真正的排序算法,并且解决了桶排序浪费空间的问题,但在算法的执行效率上却牺牲了很多,它的时间复杂度达到了O(N2)。假如我们的计算机每秒钟可以运行10亿次,那么对1亿个数进行排序,桶排序则只需要0.1秒,而冒泡排序则需要1千万秒,达到115天之久,是不是很吓人。那有没有既不浪费空间又可以快一点的排序算法
匿名组 这里可能用到几个不同的分组构造。通过括号内围绕的正则表达式就可以组成第一个构造。正如稍后要介绍的一样,既然也可以命名组,大家就有考虑把这个构造作为匿名组。作为一个实例,请看看下列字符串: “08/14/57 46 02/25/59 45 06/05/85 18 03/12/88 16 09/09/90 13“ 这个字符串就是由生日和年龄组成的。如果需要匹配年两而不要生日,就可以把正则
选择排序:从数组的起始位置处开始,把第一个元素与数组中其他元素进行比较。然后,将最小的元素方式在第0个位置上,接着再从第1个位置开始再次进行排序操作。这种操作一直到除最后一个元素外的每一个元素都作为新循环的起始点操作过后才终止。 public void SelectionSort() { int min, temp;
public struct Pqitem { public int priority; public string name; } class CQueue { private ArrayList pqueue; public CQueue() { pqueue
在编写正则表达式的时候,经常会向要向正则表达式添加数量型数据,诸如”精确匹配两次”或者”匹配一次或多次”。利用数量词就可以把这些数据添加到正则表达式里面了。 数量词(+):这个数量词说明正则表达式应该匹配一个或多个紧紧接其前的字符。 string[] words = new string[] { "bad", "boy", "baad", "baaad" ,"bear", "b
来自:http://blog.csdn.net/morewindows/article/details/6678165/归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列
插入排序算法有两层循环。外层循环会啄个遍历数组元素,而内存循环则会把外层循环所选择的元素与该元素在数组内的下一个元素进行比较。如果外层循环选择的元素小于内存循环选择的元素,那么瘦元素都想右移动以便为内存循环元素留出位置。 public void InsertionSort() { int inner, temp;
public int binSearch(int value) { int upperBround, lowerBound, mid; upperBround = arr.Length - 1; lowerBound = 0; while (lowerBound <= upper
虽然从表内第一个节点到最后一个节点的遍历操作是非常简单的,但是反向遍历链表却不是一件容易的事情。如果为Node类添加一个字段来存储指向前一个节点的连接,那么久会使得这个反向操作过程变得容易许多。当向链表插入节点的时候,为了吧数据复制给新的字段会需要执行更多的操作,但是当腰吧节点从表移除的时候就能看到他的改进效果了。 首先需要修改Node类来为累增加一个额外的链接。为了区别两个连接,这个把指
八、树(Tree)树,顾名思义,长得像一棵树,不过通常我们画成一棵倒过来的树,根在上,叶在下。不说那么多了,图一看就懂:当然了,引入了树之后,就不得不引入树的一些概念,这些概念我照样尽量用图,谁会记那么多文字?树这种结构还可以表示成下面这种方式,可见树用来描述包含关系是很不错的,但这种包含关系不得出现交叉重叠区域,否则就不能用树描述了,看图:面试的时候我们经常被考到的是一种叫“二叉树”的结构,二叉
Queue的实现: 就像Stack类的实现所做的一样,Queue类的实现用ArrayList简直是毋庸置疑的。对于这些数据结构类型而言,由于他们都是动态内置的结构,所以ArrayList是极好的实现选择。当需要往队列中插入数据项时,ArrayList会在表中把每一个保留的数据项向前移动一个元素。 class CQueue { private ArrayLis
来自:http://yingyingol.iteye.com/blog/13348911 快速排序介绍:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地
Stack的实现必须采用一种基本结构来保存数据。因为再新数据项进栈的时候不需要担心调整表的大小,所以选择用arrayList.using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Collecti
数组类测试环境与排序算法using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Data_structure_and_algorithm{ class CArray { pr
一、构造二叉树 二叉树查找树由节点组成,所以需要有个Node类,这个类类似于链表实现中用到的Node类。首先一起来看看Node类的代码。 public class Node { public int Data; public Node Left; public Node Right; public v
二叉树是一种特殊的树。二叉树的特点是每个结点最多有两个儿子,左边的叫做左儿子,右边的叫做右儿子,或者说每个结点最多有两棵子树。更加严格的递归定义是:二叉树要么为空,要么由根结点、左子树和右子树组成,而左子树和右子树分别是一棵二叉树。 下面这棵树就是一棵二叉树。         二叉树的使用范围最广,一棵多叉树也可以转化为二叉树,因此我们将着重讲解二叉树。二叉树中还有连两种特殊的二叉树叫做满二叉树和
上一节中我们学习了队列,它是一种先进先出的数据结构。还有一种是后进先出的数据结构它叫做栈。栈限定只能在一端进行插入和删除操作。比如说有一个小桶,小桶的直径只能放一个小球,我们现在向小桶内依次放入2号、1号、3号小球。假如你现在需要拿出2号小球,那就必须先将3号小球拿出,再拿出1号小球,最后才能将2号小球拿出来。在刚才取小球的过程中,我们最先放进去的小球最后才能拿出来,而最后放进去的小球却可以最先拿
msdn中的描述如下:(?= 子表达式)(零宽度正预测先行断言。) 仅当子表达式在此位置的右侧匹配时才继续匹配。例如,w+(?=d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。(?(零宽度正回顾后发断言。) 仅当子表达式在此位置的左侧匹配时才继续匹配。例如,(?此构造不会回溯。msdn描述的比较清楚,如:w+(?=ing) 可以匹配以ing结尾的单词(匹配结果不包括ing),(
1.引入线索二叉树 二叉树的遍历实质上是对一个非线性结构实现线性化的过程,使每一个节点(除第一个和最后一个外)在这些线性序列中有且仅有一个直接前驱和直接后继。但在二叉链表存储结构中,只能找到一个节点的左、右孩子信息,而不能直接得到节点在任一遍历序列中的前驱和后继信息。这些信息只有在遍历的动态过程中才能得到,因此,引入线索二叉树来保存这些从动态过程中得到的信息。 2.建立线索二叉树 为了保
排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序、买火车票会按照出发时间或者时长排序、买东西会按照销量或者好评度排序、查找文件会按照修改时间排序等等。在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序。在Donald Knuth 的计算机程序设