我先来写一下我对模板的理解:
比如想实现不同类型的数据进行相同的函数操作:
用我们之前所知道的方法就是一个函数一个函数写,这是可以的,但是你想过没有,如果每来一个类型你就需要写一个对应类型的函数,这样不仅代码的复用率极低,效率低。
所以为了解决这个问题,就得用到C++的模板,可以实现不同数据类型的相同功能。
①:函数模板
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,编译器会根据用户传入的参数去自动生成相应类型的函数!
函数模板格式:
template < typename T >
这里的typename是用来定义模板参数的关键字,也可以换成class。
②:类模板
template<class T>
class 类名
{
//类成员定义
//成员函数声明
}
要注意的是变量前面不再只是类名,而是类名<T>,还有如果成员函数的定义写在类外,还必须在成员函数的定义前再写一遍template< class T>
线性表
概念版:线性表有两种方式:
1.顺序线性表 (也就是用数组实现的,在内存中有顺序排列,通过改变数组大小实现)
2.链表 (不是用顺序实现的,用指针实现,在内存中不连续!)
顺序线性表的缺点:
1.插入和删除操作需要移动大量的元素。在顺序表上插入和删除平均要移动一半的元素。
2.表的容量难以确定。因为数组的长度要提前声明。
3.数组要求占用连续的存储空间,即使存储单元数超过所需要的数目,如果不连续也不能用。
而链式存储就没有这种缺点,每一个结点都是程序员自己向计算机申请的,如果不需要的话就会释放掉,将内存返还给系统,而且表的容量是确定的,各个节点的存储地址是不连续的,各个节点通过自己的数据域存储信息,通过指针域来存储下一个结点的信息。但如果一个结点的指针域数据丢失了,那他的下一个结点就找不到了。
单链表
单链表的构建有头插和尾插两种方法,无论是哪一种方法都需要从空表的构建开始。头插法就是新插入的每一个结点都在头节点之后,最先插入的节点变为尾节点,而尾插法是每个插入的结点都是插在链表的最后,作为尾节点出现的。这里代码就不给出。课本上都有,在链表构建好之后就可以进行一系列的操作。比如查找删除插入遍历等等。。。
双链表
如果希望除了可以确定一个结点的后继外,还可以找到它的前驱,那么我们就可以构建双链表,就是在单链表的每个结点中在设置一个指向其前驱结点的指针域。和单链表类似,它一般也是由头指针唯一确定。
循环链表
对于单链表,每个结点只存储了向后的指针,到了尾结点就停止了向后的操作。我们将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。 循环链表和单链表的主要差异在于循环的判断条件上,之前是判断temp->next是否为空,现在是temp->next不等于头结点,.循环链表最后一个结点的 link 指针不 为NULL,而是指向了表的前端。 它只要知道表中某一结点的地址,就可搜寻到所有其他结点的地址。
以上就是我对所讲的链表的理解和认识