笔记

1.    优先队列

1)    队列进出不依据进入队列的时间而是根据优先级

2)    可以讲时间复杂度可以将为nlogm

3)    算法中时间复杂度出现logn说明有一个树形结构

2.    完全二叉树

2.1) 定义:

①子节点小于父节点,除了最后一层节点之外其它层节点数为最大值,最后一层也必须集中于左侧,如图1所示:(注意这里并没有左节点必须大于右节点的说法)

3.    二叉堆(堆)

堆是先进先出,栈是先进后出,堆取元素时弹出的时顶节点的值

3.1)二叉堆是一种完全二叉树

3.2)二叉堆又分为最大堆和最小堆

①最大堆:父节点大于或等于任何一个子节点

②最小堆:父节点不大于任何一个子节点

                    Figure 1完全二叉树

树的实现????

3.3)数组存储二叉堆,二叉树有一个规律:从上到下从左到右依次编号,这样就有父节点的做节点的序号是父节点的两倍,右节点的序号是父节点的两倍加1,因此父节点parent(i)=i/2; left node(i)=2×i;right node(i)=2×i+1

4.    堆排序

4.1)原理:运用最大堆的性质之一:父节点大于等于子节点,这就保证了堆顶的元素是最大的,每次使用extract弹出的是最大元素。

原地堆排序

5.    索引堆

5.1)引出:当出现一下情况的时候传统的堆方法有一定的局限性:

①如果data中存储的数据巨大,swap操作开销太大

②当需要数据的下标和data的数据建立联系的时候,如下图所示:在一个系统中,浅灰色表示一个任务列表,第二个表示任务号,data表示优先级,如果想把任务7的优先级提升到任务列表中的2位置,只需要修改任务7的的data数据。

5.2)索引堆的就是比较data,但是交换的是索引index

/********************扩展知识*********************/

1.    迭代器:

1)容器:

①数组的维度是固定的,顶以后就不再可变,而容器是可变的,每次增加原倍数的1.5倍    

②容器只能存储引用数据类型

2)迭代器:

3)有了模板,我们可以将算法和特定的数据分离开来,而有了迭代器,我们可以将算法与特定的容器分离开来。

4)类似于指针器类型,提供了对对象的间接访问

2.    构造函数:

1)作用:初始化数据成员,在对象被创建的时候

2)构造函数不能对const类型初始化,是因为对象在程序进入构造函数体之前被创建,调用构造函数之前,常数变量已经被创建了,因此不能再对const类型赋值了。

3.    初始化列表

1)必须使用的情况:在B类中组合了一个A类对象(A类设计了构造函数),因为生成B类的对象初始化是,没有机会对A类对象进行初始化,相关语法如下:

  constructor::constructor():m1(v1),m2(v1,v2),m3(v3)

其中constructor为类B constructor是类B的构造函数冒号后边的是参数列表

Class A{

public:

              A(int_a){

              a = -a

              }

private:

              int a;

}

class B{

public:

              B(intb1,int b2):a1(1),a2(2)

{

              }

              //经典用法如下

              /对构造函数B进行重载

              B(int b1, int b2,int m, int n):a1(m),a2(n)

              {

             

              }

private:

              intb1,b2;

              A a1,a2;

}

int main(){

       B object(1,2);//这里出现错误,如要防止错误的出现就需要在B的构造函数引入参数列表(红字部分);

       Bobject(1,2,3,4);

}

调用顺序:先执行被组合对象的构造函数,如果组合对象有多个,按照定义顺序是不是初始化列表的顺序执行

2)有参数拷贝构造函数(赋值构造函数)

①一个对象初始化另外一个对象

②语法constructor::constructor(const constructor &)

③调用有参数构造函数方法:

constructor t1(v1,v2)

constructor t2 = (v1,v2)

constructor t3 = constructor(1,2);//这里产生一个匿名对象,

3)拷贝构造函数

3.1)拷贝构造函数使用场合:

       ①通过使用另一个对象来初始化新创建的对象

       ②复制对象把它作为参数传递给函数

       ③复制对象并从函数返回这个对象

3.2)当类中带有指针变量,并有动态内存分配的时候,必须定义拷贝构造函数,标准定义如下:

       classname(const classname &obj){

         //函数主体

       }

3.3)实例:

int main(){
    Lineline(10);
    display(line);
    return0;
} 在调用display时符合3.1中的②把对象传递给函数需要拷贝构造函数

3.4)拷贝构造函数临时变量

test对象传入形参时functiontest),会先会产生一个临时变量,就叫 C 吧。

然后调用拷贝构造函数把test的值给C整个这两个步骤有点像:CExampleC(test);

g_Fun()执行完后, 析构掉 C 对象。

Maxheap<int> myheap = Maxheap<int>(100);这种初始化对象的方式是使用默认构造函数

Maxheap<int> maxheap1 = maxheap; Maxheap<int> maxheap1(maxheap);

这两种情况下调用拷贝构造函数

4)赋值函数(与拷贝构造函数不同)

https://www.cnblogs.com/duwenxing/p/7445927.html

在自定义类中重载运算符“=”号,即

classname &operator=classname & obj{

赋值函数体

}

这里使用引用作为返回值是因为引用不会创建一个副本,不用引用的会创建一个副本,如果参数不使用引用的话会产生一个临时对象,详情见如下网址:

https://blog.csdn.net/qq_33266987/article/details/53516977

4.    类模板 template <class T> ==template <typename T>用法完全一样

5.    链表类包含:

7.1) 结构体:①Data②指向下一个节点的指针

7.2) 迭代器类,这里封装成类是因为要对迭代器的++,--,*运算都重载

7.3) 涉及到链表或是容器要有获取容器头,插入,定义迭代器类型操作,迭代器就是一个指针,

6.    运算符重载:

8.1)基本语法:<函数类型> operator <运算符>(参数表){}

8.2)运算符重载的参数列表和操作数匹配的问题,一员或者二元运算符作为成员函数的时候,第一操作数就是对象本身,其并不显式的出现在参数列表中,即第一操作数仅以this指针的形式隐含于参数表中,所以对于一元操作数参数列表可以为空,而对于二元运算符成员函数,参数列表中只有一个操作数,它代表第二个操作数。

7.    排序算法总结

10.1)算法稳定性:对于相同的元素排序后他们之间的相对顺序不变

10.2) 插入排序和归并排序是稳定的


阅读更多

没有更多推荐了,返回首页