天天看點

C++語言------順序表實作,用動态數組的方法

C++語言------順序表實作,用動态數組的方法

C++ 中常用的一些東西,通過使用動态數組來實作順序表,

掌握了一下知識點:

1.預處理有三中方法

宏定義,檔案包含,條件編譯

2.使用同名的變量時,可以在外層使用命名空間 類解決變量名重定義的錯誤

3.類中三個通路權限,

public :    公有通路權限,主要寫一些函數接口

protected:  保護通路

private     私有通路權限      封裝性,

4.構造函數\析構函數

5.重載運算符

sub.h檔案

/*
    實作一個順序表
    1.建立類.成員包含.指向順序表的指針,順序表的長度,順序表的元素個數
    2.實作功能:添加,删除,修改,檢視
*/
//用頭檔案進行聲明的時候,可以使用 ifnedf endif
#ifndef __SUB_H__    
/*
    #ifndef  是if not define 的簡寫 
    它是預處理功能三種(宏定義,檔案包含,條件編譯)的條件編譯
    再C++中使用可以避免出現 " 變量重複定義的錯誤  "
*/
#define __SUB_H__
#include <iostream>
using namespace std;

//使用作用域,保證函數名不會出錯
namespace data
{
    //建立vector類
    class vector
    {
        //定義私有成員,包括指向空間的指針,空間大小,空間元素個數
    private:
        int *element = nullptr;
        size_t count = 0;    //size_t 是位址線寬度 int是資料線寬度,
        size_t length = 0;
        //定義保護成員  新空間不足需要生成新空間
    protected:
        bool re_new(int size);
        //定義公有成員函數包括:構造函數,析構函數,成員其它函數
    public:
        //可以統一使用傳回值為bool的來确定函數的使用情況
        //析構函數 進行初始化的作用 
        //這裡首先,初始化一下,預設參數 在這裡聲明 定義不用
        vector(int count=10);

        //析構函數 進行指針等的釋放工作
        ~vector();

        //順序表添加  使用bool為傳回值,友善檢測是否函數運作成功
        //插入需要兩個參數:分别是插入的位置,插入的内容
        bool insert(int index, int elem);

        //順序表删除  隻需要插入删除的位置即可
        bool erase(int index);

        //重載[] 進行内容的查找及修改
        int & operator[](int index);
        //檢視元素個數
        int Ssize()const { return length; }
        //運算符重載,友善輸出
        //使用友元函數重載cout運算符
        friend ostream & operator<<(ostream & o, const vector & vec);
    };

}

#endif // !__SUB_H__      

sub.cpp檔案

#include "sub.h"
using namespace std;
//前邊類定義了作用域,這裡需要使用才能通路
namespace data
{
    //構造函數   需要作用域來明确函數屬于哪裡
    vector::vector(int count )    //參數已經為10,在聲明中
    {
        //初始化基本成員變量
        //因為要使用類内的count來指派,碰到相同變量名,
        //使用this指針來區分.有this指針的是屬于類的變量
        this->count = count;
        length = 0;        //元素個數,初始為0
        //初始化指向順序表空間的指針
        //在堆内申請空間,空間大小為count 
        element = new int[count];  //  = {0}; 初始化繁瑣
        //申請完空間需要對空間進行初始化 \
         使用memset(指針變量,初始值, 空間大小 )
        memset(element ,0,sizeof(int)*count);
    }
    //析構函數   析構沒參數, 構造有參數,參數可變
    //析構函數    用來釋放對象占用的空間
    vector::~vector()
    {
        //首先釋放指向空間的指針
        //判斷指針現在是否為空
        if (element!=nullptr)
        {
            //使用 new 申請, delete 進行釋放,
            //這裡使用方括号是因為 申請時, 類型是 int[] 
            delete[] element;
        }
        //初始化元素個數
        length = 0;
    }
    //順序表插入\添加
/*
    需要考慮:
    1.插入的位置是否合适,有可能插入的是-1的位置,數組下标最小為0,-1就會出現錯誤
    2.判斷空間大小,因為空間大小是初始設定的,在添加資料時有可能資料超出
    3.添加元素的位置,需要講後邊的所有元素向後移動一位,才能空出來
    4.将空出來的位置指派需要的元素
    5.将元素個數 +1
    6.傳回成功
*/
    //index 為插入的位置, elem為插入的元素内容
    //不要忘記類的作用域
    bool vector::insert(int index ,int elem)
    {
        //1.判斷位置
        if (index<0 || index >length)
        {
            //因為不合适,是以需要退出程式
            return false;
        }
        //2.判斷空間大小  看元素個數是否和空間大小相等,相等說明空間不足
        if (length == count)
        {
            //相等說明空間不足,需要開辟新記憶體
            //這裡直接使用 類的成員函數, 如果開辟空間失敗需要提示一下
            if (!re_new(count+10))
            {
                printf("空間申請失敗!");
                //使用system 讓使用者看到提示
                system("pause");
                //exit為C++的退出函數,exit(0)正常退出,非0 非正常退出
                exit(-1);
            }
        }
        //3.插入位置移動  通過循環周遊,位置,将位置後移
        //這裡的i 需要等于元素的個數, 因為總長度才能找到對應 存在的位置
        //當i到需要插入的位置時,在向後移動一次,就可以空出這個位置了
        for (int i=length-1; i>=index; --i )
        {
            //将目前位置元素移動到下一個位置,
            element[i + 1] = element[i];
        }
        //将插入位置 指派内容
        element[index] = elem;
        //因為插入了一個内容是以需要将元素個數 +1
        ++length;
        //傳回成功
        return true;
    }
    //删除元素
/*
    需要考慮:    
    1.判斷位置是否有效
    2.删除的位置,後邊的依次向前移動一位
        這裡需要注意,最後一位的問題.因為是依次向前移動,是以需要将最後一位指派為0 ,
        就是說:最後一個元素的下一位也要向前移動,覆寫原來的元素
    3.将元素個數 -1
    4.傳回成功
*/
    //隻需要删除的位置即可
    bool vector::erase(int index)
    { 
        //1.判斷位置  因為length表示多少個元素,是以 length -1 是下标的位置
        if (index <0 || index >length-1)
        {
            return true;
        }
        //2.删除元素
        for (int i =index;i<=length-1;i++ )
        {
            element[i] = element[i + 1];
        }
        //3.元素個數 -1
        --length;
        //4. 傳回成功
        return true;
    }
    //重載[] 友善存取元素
    int & vector::operator[](int index)
    {
        //重載運算符,不能改變運算符的性質,
        //[]就是一個下标值,是以這裡可以進行,查詢和修改
        return element[index];
    }
    //開辟新空間   調用此函數說明空間不足,需要重新配置設定
    bool vector::re_new(int size)
    {
        //申請堆空間,大小為 size 是實參傳進來比原空間大10的數,
        //如果向讓程式更優,這裡需要設定成原數的2倍,避免多次配置設定空間
        int* new_element = new int[size];
        //申請堆空間後,需要初始化  使用memset
        memset(new_element , 0 , sizeof(int)*size);
        //這裡還要檢測一下空間是否申請成功
        if (!new_element)  //申請成功傳回的是1,取反,就是0 ,不進入判斷
        {
            return false;
        }
        //将原空間的内容拷貝到新空間   使用memcpy函數
        memcpy(new_element,element,this->count*sizeof(int));
        //釋放原來空間
        delete[] element;
        //将指針指向新空間
        element = new_element;
        //這裡不要忘記, 原來空間替換成新空間大
        this->count = size;
        //傳回成功
        return true;
    }
    //因為這裡是友元函數,是以屬于一個全局函數,不需要類名作用域
    ostream& operator<<(ostream & o,const vector & vec)
    {
        for (int i=0;i<vec.Ssize();i++)
        {
            //endls 是 輸出一個空格 
            o << vec.element[i] << ends;
        }
        return o;
    }



}      

main.cpp檔案

#include "sub.h"

int main()
{
    //這裡需要作用于來定義類的對象
    //當建立對象以後,構造函數就執行
    data::vector vec(10);
    //寫入元素
    for (int i =0;i<30;i+=2)
    {
        vec.insert(0, i + 1);
    }
    //經過運算符重載,vec可以直接輸出
    cout << vec << endl;
    // 查詢第幾個位置,第幾個值
    cout << vec.operator[](5) << endl;
    //将第幾個值,修改成多少
    vec.operator[](5) = 555;
    cout << vec << endl;

    return  0;

}      

posted on 2019-03-01 15:44 0x0000開始 閱讀(...) 評論(...) 編輯 收藏

繼續閱讀