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;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM