zoukankan      html  css  js  c++  java
  • C++day15 学习笔记

    1、在头文件中

      #ifndef _ACCOUNT_   //预编译选项,表示如果没有定义这个宏
      #define _ACCOUNT_   //创建以_ACCOUNT_命名的宏
                            并声明类
      #endif 

    2、链表
       (1)解决数组必须连续存储的问题
            链表是可以不连续的,通过每个节点的指针连接
       (2)节点中一部分空间用于存放数据,另一部分是一个指向下一个节点的指针       
       (3)每个节点都是一个结构

           struct node{
                 int data;    //存储数据
                 node* next;  //指向下一个节点的指针,是自己这个结构的类型
            }

       (4)尾节点 --- 链表中的最后一个节点 --- 指针指向NULL
            头节点 --- 要访问链表中的元素,必须要知道头节点的位置
                       把地址放在一个指针中 --- 头指针指向头节点,只是一个指针 --- 是必须存在的元素
       (5)对链表的常见操作 --- 增删改查
       (6)链表与数组的区别
            数组:空间必须连续,数组是定长的,插入和删除需要遍历整个数组,效率不高。
                  取元素可直接使用下标,访问方便
            链表:空间在内存中不必连续,通过指针连接
                  链表是不定长的,可以随时添加新节点,通过指针关联
                  对链表的插入删除,不需要移动节点位置,只对指针操作即可
                  访问元素,要从头指针开始遍历
                 
            当数据需要频繁的插入删除的时候,需要使用链表
            当改动不大,查询频繁的时候,使用数组
            潜规则 : 能用数组就不用链表

    View Code
            ======================================================================
                                          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
    View Code
            ======================================================================
                                      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) 插入. 示例代码如下:

    View Code
    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) 查找. 示例代码如下:

    View Code
        Node* & find( bnode* & root, const DATA& cd )
        {
            if( root==NULL )                    // 如果root节点是空,则为空树
                return root;                    // 返回root指向的地址,即NULL
            else if( root->data==cd )           // 如果root节点就是要查找的数值
                return root;                    // 返回root指向的地址,为了清晰,和上面的分开写
            else if( cd < root->data )          // 如果root节点指向的值大于要查找的值
                return find( root->left, cd );  // 返回查找root的左子树返回的地址
            else
                return find( root->right, cd ); // 否则返回查找root的右子树返回的地址
        }

    3) 删除. 示例代码如下:
       被删除的是树根(1)则选择右子树的树根做新树根,左子树可以整个挂在右子树最左侧的一个左节点上
                          右子树中最左边的一个节点,是最靠近左子树的树根的     
                     (2)让左子树中的最大节点做新树根

    View Code
    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 ;
    }

    作业:修改链表程序,能够删除全部相同元素;在指定位置后插入数据

  • 相关阅读:
    ajax工作原理
    ajax 和xmlHttpRequest区别
    ajax 基本语法
    javascript 中XMLHttpRequest 实现前台向后台的交互
    Javascript 中ajax实现前台向后台交互
    javascript 中函数eval()
    两道有趣的面试题
    linux 中的快捷键
    linux awk命令详解
    linux sed命令详解
  • 原文地址:https://www.cnblogs.com/tangzhengyue/p/2622634.html
Copyright © 2011-2022 走看看