C++day15 学习笔记
1、在头文件中
#ifndef _ACCOUNT_ //预编译选项,表示如果没有定义这个宏#define _ACCOUNT_ //创建以_ACCOUNT_命名的宏并声明类#endif
2、链表
(1)解决数组必须连续存储的问题
链表是可以不连续的,通过每个节点的指针连接
(2)节点中一部分空间用于存放数据,另一部分是一个指向下一个节点的指针
(3)每个节点都是一个结构
struct node{int data; //存储数据node* next; //指向下一个节点的指针,是自己这个结构的类型}
(4)尾节点 --- 链表中的最后一个节点 --- 指针指向NULL
头节点 --- 要访问链表中的元素,必须要知道头节点的位置
把地址放在一个指针中 --- 头指针指向头节点,只是一个指针 --- 是必须存在的元素
(5)对链表的常见操作 --- 增删改查
(6)链表与数组的区别
数组:空间必须连续,数组是定长的,插入和删除需要遍历整个数组,效率不高。
取元素可直接使用下标,访问方便
链表:空间在内存中不必连续,通过指针连接
链表是不定长的,可以随时添加新节点,通过指针关联
对链表的插入删除,不需要移动节点位置,只对指针操作即可
访问元素,要从头指针开始遍历
当数据需要频繁的插入删除的时候,需要使用链表
当改动不大,查询频繁的时候,使用数组
潜规则 : 能用数组就不用链表
======================================================================link.h======================================================================#ifndef _LINK_#define _LINK_using namespace std;class Node{ //节点类 public :int val; //保存数据 Node* next ; //保存下一个节点的地址 Node(){ //构造函数,把指针初始化为NULL next = NULL; } };class Link{protected :Node* head; //头指针 public :Link();~Link();void insertTail(int);void insertHead(int);void del(int);int indexOf(int); //查询一个元素的下标void update(int , int);void disp(); };#endif
======================================================================link.cc====================================================================== #include "link.h"#include <iostream>using namespace std;Link::Link(){head = NULL; }Link:: ~Link(){//释放空间,从头向尾释放 if(head != NULL){Node *p = head;head = head->next; //把头节点向后移动 delete p; //抛弃原来的那个头节点cout << "delete one ... " << endl; }}//尾插入 void Link::insertTail(int v){Node *p = new Node;p->val = v; if(head == NULL){head = p; //让新节点的指针指向新节点,即把新节点的地址保存在头指针中return ; } Node * temp = head ; //用一个临时指针,从头节点开始找到 尾while(temp -> next != NULL){ //表示temp不是尾节点 temp = temp -> next ; //用temp后面的一个指针为自己赋值,即指向下一个节点 } temp -> next = p; //尾插入,最后一个节点的指针保存新节点的地址 }//头插入 void Link::insertHead(int v){Node *p = new Node; //创建新节点 p->val = v ; //保存数据 p->next = head; //让新节点的指针和头指针一样指向第一个节点 head = p; //让头节点指向新节点 }void Link::del(int v){ //找到被删除的节点 ,if(head == NULL ){return ; }if(head -> val == v){Node *p = head;head = head->next;delete head;} Node *p1 = head->next; //找值相同的一个 Node *p2 = head ; //跟在p1后面while(p1 != NULL){if(p1->val == v){p2->next = p1 -> next;delete p1;break;} p1 = p1->next;p2 = p2->next; } }int Link::indexOf(int v){ //查询一个元素的下标Node * p = head ;int counter = 0 ;while( p != NULL ){if( p->val == v ){return counter ;}p=p->next ;counter++ ;}return -1 ; } void Link::update(int v1 , int v2){Node * p = head ;while( p != NULL ){if( p->val == v1 ){p->val = v2 ;}p = p->next ;} }void Link::disp(){Node *p = head;while(p != NULL){cout << p->val << " " ; p = p->next;} cout << endl;}
3、二叉树
每个节点最多只有两个分支的树,它有一个根指针,要指向这棵树的根节点(最顶端的节点).
左子树上的值小于其父节点的值,右子树上的值都大于其父节点上的值。 --- 排序二叉树
(1)周游(遍历) :先序 --- 中左右
中序 --- 左中右
后序 --- 左右中
(2)非常方便查找
二叉查找树的常见操作:
1) 插入. 示例代码如下:
Node* Tree::_insert(int v, Node* r){ //真正实现插入操作,返回插入以后的根 if(r == NULL){ //是一棵空树 (空子树) Node* p = new Node(v); //创建新节点 r = p; //让新节点成为根或者子节点 return r;}if( v < r->val){ //插到左子树上 r->left = _insert(v,r->left);return r;}else{ //插到右子树上 r->right = _insert(v,r->right); return r;} }
2) 查找. 示例代码如下:
Node* & find( bnode* & root, const DATA& cd ){if( root==NULL ) // 如果root节点是空,则为空树return root; // 返回root指向的地址,即NULLelse if( root->data==cd ) // 如果root节点就是要查找的数值return root; // 返回root指向的地址,为了清晰,和上面的分开写else if( cd < root->data ) // 如果root节点指向的值大于要查找的值return find( root->left, cd ); // 返回查找root的左子树返回的地址elsereturn find( root->right, cd ); // 否则返回查找root的右子树返回的地址}
3) 删除. 示例代码如下:
被删除的是树根(1)则选择右子树的树根做新树根,左子树可以整个挂在右子树最左侧的一个左节点上
右子树中最左边的一个节点,是最靠近左子树的树根的
(2)让左子树中的最大节点做新树根
Node* _del( int value , Node* r ){if( r == NULL ){ //删除空树return r ;}if( r->value == value ){ //删除树根if(r->left==r->right){ //左右子树都是NULL的情况下 delete r ;return NULL;}else if( r->right == NULL ){ //只有右子树,没有左子树的时候 Node * p = r;r = r->left ;delete p ;return r ;}else if( r->left == NULL ){ //只有右子树,没有左子树Node *p = r ;r=r->right ;delete p ;return r ;}else{ //左右子树都有Node * p1 = r -> right ;Node * p2 = r -> right ;while( p2->left != NULL ){p2 = p2->left ;} p2->left = r->left ; delete r ;return p1 ;} }if( value <= r->value ){r->left = _del( value , r->left);return r ;}else{r->right =_del( value, r->right );return r ;} return r ; }
作业:修改链表程序,能够删除全部相同元素;在指定位置后插入数据
转载于:https://www.cnblogs.com/tangzhengyue/archive/2012/08/04/2622634.html
C++day15 学习笔记相关推荐
- Python学习笔记:Day15 部署Web App
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- Python学习笔记:Day 16 编写移动App
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- kali视频学习笔记
DAY1 系统安装 1. 用u盘烧录KALI镜像,不含live开头,含amd64,4G 2. 用u盘启动安装图形界面,选简单中文-汉语,默认KFCE,全工具 3. 改密码,sudo passwd ro ...
- python学习笔记02
python学习笔记02 面向对象Object Oriented 概述 类和对象 封装 继承 多态 类与类的关系 设计原则 总结 python学习笔记03 面向对象Object Oriented 概述 ...
- PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call
您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...
- 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移
暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...
- 2020年Yann Lecun深度学习笔记(下)
2020年Yann Lecun深度学习笔记(下)
- 2020年Yann Lecun深度学习笔记(上)
2020年Yann Lecun深度学习笔记(上)
最新文章
- JVM - 基本类型的包装类和对象池
- Node.js进击基础一(5-5http知识填坑)
- JavaScript变量和对象参数传值问题
- 【CyberSecurityLearning 附】域的复习+小综合实验(重要!)
- 数学建模国赛 常考赛题类型(模拟退火算法、粒子群算法、遗传算法)
- Java spark中的各种范型接口Function的区别(持续更新中)
- formSelects-v4.js 基于Layui的多选解决方案
- 从0成为Facebook广告高手系列教程,Facebook广告数据分析上篇
- 开始启用51CTO的博客
- 移动互联软件技术与实践demo
- Javaweb的初级(Servlet接口)
- 那些你该知道的CSS颜色代码大全都在这里了,点击查阅
- laravel数据填充seeder
- 世界是客观存在的吗?
- 时序分析 43 -- 时序数据转为空间数据 (二) 马尔可夫转换场
- python 实现图片批量加入水印!
- 如何免费获取文件高速下载直链
- 条码打印软件如何设置双排标签纸尺寸 1
- hihoCoder #1079 离散化
- mac按键难回弹(按下去软软的)