鱼C论坛

 找回密码
 立即注册
查看: 1380|回复: 3

[技术交流] 如何实现一个动态顺序线性表(手动打造vector)

[复制链接]
发表于 2019-11-21 10:00:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、简介
        相信学c++的小伙伴们都知道c++的库里有一个特别好用的动态数组Vector吧,但是各位小伙伴知道怎么实现的么?
        这里我就带大家手动打造一个自己的vector,话不多说,上代码(注释很详细哦)
二、代码
#include <stdio.h>
#include <stdlib.h>

template <typename T>
class CList {
public:
        //初始化线性表,空间大小为10
        void Init()
        {
                m_nLength = 0;
                m_nSize = 10;
                m_List = (T*)malloc(m_nSize * sizeof(T));
        }
        //在指定位置插入元素
        bool Insert(unsigned int nIndex, const T& elem)
        {
                //如果插入元素的地址无法访问,则插入失败
                if (nIndex<0 || nIndex>m_nLength)
                        return false;
                //判断插入元素后是否需要重新分配内存
                if (m_nSize < m_nLength + 1)
                {
                        m_List = (T*)realloc(m_List, m_nSize * sizeof(T) * 2);
                        if (m_List == NULL)
                                return false;
                        m_nSize *= 2;
                }
                //进行插入操作
                for (int i = m_nLength; i > nIndex; i--)
                {
                        m_List[i] = m_List[i - 1];
                }
                m_List[nIndex] = elem;
                m_nLength++;
                return true;
        }
        //在指定位置插入n个相同的元素
        bool Insert(unsigned int nPos, unsigned int nNum, const T& elem)
        {
                //如果插入元素的地址无法访问,则插入失败
                if (nPos<0 || nPos>m_nLength)
                        return false;
                //判断插入元素后是否需要重新分配内存
                if (m_nSize < m_nLength + nNum)
                {
                        m_List = (T*)realloc(m_List, m_nSize * sizeof(T) * 2);
                        if (m_List == NULL)
                                return false;
                        m_nSize *= 2;
                }
                //开始插入元素
                //从后往前移位
                for (int i = m_nLength + nNum - 1; i >= (nPos + nNum); i--)
                {
                        m_List[i] = m_List[i - nNum];
                }
                m_nLength += nNum;
                //放入元素
                while (nNum--)
                {
                        m_List[nPos++] = elem;
                }
                return true;
        }
        //在指定位置删除元素
        bool Remove(unsigned int nIndex)
        {
                //如果删除元素的地址无法访问,则删除失败
                if (nIndex<0 || nIndex>m_nLength)
                        return false;
                //开始删除元素
                m_nLength--;
                for (int i = nIndex; i < m_nLength; i++)
                {
                        m_List[i] = m_List[i + 1];
                }
                return true;
        }
        //重载下标运算符,使其可以直接修改元素
        T& operator[](unsigned int nIndex)
        {
                //如果元素的地址无法访问,则输出错误信息
                if (nIndex < 0 || nIndex >= m_nLength)
                        printf("访问越界\n");
                return m_List[nIndex];
        }
        //查找元素
        int SearchElem(const T& elem)
        {
                int nIndex = 0;
                while (nIndex < m_nLength)
                {
                        if (m_List[nIndex] == elem)
                                break;
                        nIndex++;
                }
                //没有找到
                if (nIndex == m_nLength)
                        nIndex = -1;
                return nIndex;
        }
        //返回当前长度
        int GetLength()
        {
                return m_nLength;
        }
        //清空线性表
        void Clear()
        {
                memset(m_List, 0, m_nSize*(sizeof(T)));
                m_nLength = 0;
        }
        //线性表元素入栈
        void push_back(const T& elem)
        {
                //判断插入元素后是否需要重新分配内存
                if (m_nSize < m_nLength + 1)
                {
                        m_List = (T*)realloc(m_List, m_nSize * sizeof(T) * 2);
                        if (m_List == NULL)
                                return;
                        m_nSize *= 2;
                }
                m_List[m_nLength] = elem;
                m_nLength++;
        }
        //线性表尾部元素出栈
        T& pop_back()
        {
                m_nLength--;
                return m_List[m_nLength];
        }
        //返回某一位置的元素
        T at(unsigned int nIndex)
        {
                return m_List[nIndex];
        }
private:
        T* m_List;
        int m_nLength;
        int m_nSize;
};

int main()
{
        CList<int> objList;
        objList.Init();
        for (int i = 0; i < 10; i++)
                objList.push_back(i);
        for (int i = 0; i < 10; i++)
                printf("%3d", objList[i]);
        printf("\n");
        objList.Insert(9, 5, 11);
        for (int i = 0; i < 15; i++)
                printf("%3d", objList[i]);
        printf("\n");
        while (objList.GetLength() != 0)
        {
                printf("%3d", objList.pop_back());
        }
        printf("\n");
        return 0;
}
三、结束语
        嗯,可能还有一些小bug,但是大致功能实现了,欢迎各位大佬指正
        也希望和各位小伙伴们交流学习,共同进步
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-21 10:01:16 | 显示全部楼层
唉,之前的帖子被吃掉了,好难受,这篇是补发的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-21 18:21:01 | 显示全部楼层
顶一顶
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-21 19:42:25 | 显示全部楼层
再来个析构函数就完美了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-4 23:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表