Data Structure

4 篇文章 0 订阅
3 篇文章 0 订阅


数据结构

包括数据对象和实例,以及构成实例的每个元素之间所存在的各种关系,这种关系可由函数实现。
数据描述

  1. 公式化描述:所有元素连续存储(如:数组,string);
  2. 链接描述:每个元素包含下一个元素的地址(如:链表,list);
  3. 间接寻址:用一张表,收集所有元素的地址;
  4. 模拟指针:类似链表描述,只是用整数代替指针,此整数包含下一个元素的标志,标志也是整数。
    线性表(linear list)

实例形式为:(E1, E2,E3,E4……En)。其中n是有穷自然数,其中Ei是表中的元素,n为表的长度(即元素个数)。如:数组
线性表唯一的关系:优先关系。如:E1优先于E2,E2优先于E3…….
线性表的抽象数据类型描述


线性表 数组

抽象数据类型LinearList{
实例
0或多个元素的有序集合
操作
Create(): 创建一个空线性表
Destroy(): 删除表
IsEmpty(): 如果表为空则返回 t r u e,否则返回false
Length(): 返回表的大小 (即表中元素个数)
Find(k,x): 寻找表中第k 个元素,并把它保存到 x 中;如果不存在,则返回f a l s e
Search(x): 返回元素x在表中的位置;如果x 不在表中,则返回0
Delete(k,x): 删除表中第k 个元素,并把它保存到 x 中;函数返回修改后的线性表
Insert(k,x): 在第k个元素之后插入x;函数返回修改后的线性表
Output(out): 把线性表放入输出流 out 之中
} 
#ifndef F_DATA_STRUCT_LINEAR_LIST_ARRAY_20170908_9_44_JHASKDFJHASF_H_
#define F_DATA_STRUCT_LINEAR_LIST_ARRAY_20170908_9_44_JHASKDFJHASF_H_


#ifndef F_DATA_STRUCT_LINEAR_LIST_ARRAY_20170908_9_44_JHASKDFJHASF_H_
#define F_DATA_STRUCT_LINEAR_LIST_ARRAY_20170908_9_44_JHASKDFJHASF_H_


/*
数据结构算法与应用-C++语言描述.pdf
第三章 数据描述
第三节 公式化描述
数据结构:线性表 数组
*/

////////////////////////////////////////////////////////////////////////////
//C++语言实现
////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"

using namespace std;

const int N_ARRAY_INIT_SIZE = 10;   //初始化分配空间的大小
const int N_ARRAY_INCREMENT = 10;   //每次分配空间的增量

enum E_Status
{
    STATUS_ERROR    = -1,
    STATUS_SUC      = 1
};

template<class T>
void TraceData(const T &pData, int nDataSize)
{
    const char *tType= typeid(T).name();

    for (int i=0; i<nDataSize; i++)
    {
        if (0 == strcmp(tType, "int"))
        {
            TRACE("%d  ", pData[i]);
        }
        else if (0 == strcmp(tType, "float"))
        {
            TRACE("%f  ", pData[i]);
        }
    }

    TRACE("\n");
}

template<class T>
class ListArray 
{
public:
    ListArray(int nNewSize = 10);
    ~ListArray();

    //! 根据索引, 插入数据
    int InsertData(const T &eData, const int nInserIndex);

    //! 输出所有数据
    void Printf();

    //! 根据索引,获取当前数据
    bool GetDataByIndex(T &eData, const int nIndex);

    //! 根据数据,获取当前数据的索引
    bool GetIndexByData(const T &eData, int &nIndex);

    //! 获取当前数据个数
    int GetCurDataSize();

    //! 判断是否为空
    bool IsEmpty();

    //! 根据索引,删除数据,并将后面的数据前移
    bool DeleteDataByIndex(const int nIndex);

    //! 排序:直接插入排序算法
    bool StraightInsertionSort(T *pData, const int nSize);

    //! 排序:选择排序算法
    bool SelectionSort(T *pData, const int nSize);

public:
    T *m_pElem;         //存数据基地址
    int m_nCurSize;     //当前大小
    int m_nTotalSize;   //容量
};

template<class T>
ListArray<T>::ListArray(int nNewSize)
:m_nCurSize(0)
,m_nTotalSize(0)
{
    if(nNewSize <= 0)
    {
        return;
    }

    m_pElem = (T *)malloc(nNewSize * sizeof(T));
    if (!m_pElem)
    {
        return ;
    }

    m_nCurSize      = 0;
    m_nTotalSize    = nNewSize;
}

template<class T>
ListArray<T>::~ListArray()
{
    free(m_pElem);
    m_pElem = NULL;
}

//根据索引, 插入数据
template<class T>
int ListArray<T>::InsertData(const T &eData, const int nInserIndex)
{
    if ((nInserIndex<0) || (nInserIndex > m_nCurSize))
    {
        return STATUS_ERROR;
    }

    //内存空间不够,重新分配新内存
    if(m_nTotalSize <= m_nCurSize)
    {
        T *pNewArray = (T*)realloc(m_pElem, (m_nTotalSize + N_ARRAY_INCREMENT) * sizeof(T));
        if (!pNewArray)
        {
            return STATUS_ERROR;
        }

        m_pElem = pNewArray;
        m_nTotalSize += N_ARRAY_INCREMENT;
    }

    T *pInsertE = &m_pElem[nInserIndex];

    //将插入索引后面的数据后移一个位置
    T *pMoveE;
    for(pMoveE=&m_pElem[m_nCurSize]; pMoveE>=pInsertE; pMoveE--)
    {
        int nData =  *(pMoveE-1);
        *pMoveE = *(pMoveE-1);
    }

    *pInsertE = eData;
    m_nCurSize += 1;

    return STATUS_SUC;
}

//输出所有数据
template<class T>
void ListArray<T>::Printf()
{
    const char *tType= typeid(T).name();

    T eData = 0;
    for (int i=0; i<m_nCurSize; i++)
    {
        eData = m_pElem[i];
        cout <<eData;

        if (0 == strcmp(tType, "int"))
        {
            printf("%d /n", eData);
        }
        else if (0 == strcmp(tType, "float"))
        {
            printf("%f /n", eData);
        }
    }
}

//根据索引,获取当前数据
template<class T>
bool ListArray<T>::GetDataByIndex(T &eData, const int nIndex)
{
    if((nIndex<0) || (nIndex>=m_nCurSize))
    {
        return false;
    }

    eData = m_pElem[nIndex];

    return true;
}

//根据数据,获取当前数据的索引
template<class T>
bool ListArray<T>::GetIndexByData(const T &eData, int &nIndex)
{
    nIndex = -1;

    for(int i=0; i<m_nCurSize; i++)
    {
        if (m_pElem[i] == eData)
        {
            nIndex = i;
            break;
        }
    }

    return nIndex >= 0 ? true : false;
}

//获取当前数据个数
template<class T>
int ListArray<T>::GetCurDataSize()
{
    return m_nCurSize;
}


//判断是否为空
template<class T>
bool ListArray<T>::IsEmpty()
{
    return m_nCurSize == 0 ? true : false;
}

//根据索引,删除数据,并将后面的数据前移
template<class T>
bool ListArray<T>::DeleteDataByIndex(const int nIndex)
{
    if((nIndex < 0) || (nIndex>=m_nCurSize))
    {
        return false;
    }

    for (int i=0; i<m_nCurSize; i++)
    {
        if (i>=nIndex)
        {
            m_pElem[i] = m_pElem[i+1];
        }
    }

    m_nCurSize--;
    return true;
}

//排序:直接插入排序算法
template<class T>
bool ListArray<T>::StraightInsertionSort(T *pData, const int nSize)
{
    if (nSize <= 1)
    {
        return false;
    }

    TRACE("排序:直接插入排序算法\n");

    T nCurTempDataI(0);
    for (int i=1; i<nSize; i++)
    {
        nCurTempDataI = pData[i];

        for (int j=i-1; j>=0; j--)
        {
            if (nCurTempDataI <= pData[j])
            {
                pData[j+1]  = pData[j+1] + pData[j];
                pData[j]    = pData[j+1] - pData[j];
                pData[j+1]  = pData[j+1] - pData[j];
            }
        }

        TraceData(pData, nSize);
    }

    return true;
}

//排序:选择排序算法
template<class T>
bool ListArray<T>::SelectionSort(T *pData, const int nSize)
{
    if (nSize <= 1)
    {
        return false;
    }

    TRACE("排序:选择排序算法\n");

    int nMinIndex(0);
    for(int i=0; i<nSize-1; i++)
    {   
        for(int j=i+1; j<nSize; j++)
        {
            if (pData[nMinIndex] >= pData[j])
            {
                nMinIndex = j;
            }
        }

        if (pData[i] != pData[nMinIndex])
        {
            pData[i] = pData[i] + pData[nMinIndex]; 
            pData[nMinIndex] = pData[i] - pData[nMinIndex]; 
            pData[i] = pData[i] - pData[nMinIndex]; 
        }

        TraceData(pData, nSize);
    }

    return true;
}

void F_Chapter_3_3_Code()
{
    ListArray<int> listArray(N_ARRAY_INIT_SIZE);

    //根据索引, 插入数据
    for (int i=0; i<10; i++)
    {
        listArray.InsertData(i, 0);
    }
    /*
    listArray.InsertData(22, 5);
    listArray.InsertData(88, 5);
    */

    //输出所有数据
    listArray.Printf();

    int nTest = -1;
    bool bTest = false;
    //根据索引,获取当前数据
    bTest = listArray.GetDataByIndex(nTest, listArray.GetCurDataSize()-2);

    //根据数据,获取当前数据的索引
    bTest = listArray.GetIndexByData(99, nTest);

    //判断是否为空
    bTest = listArray.IsEmpty();

    //根据索引,删除数据,并将后面的数据前移
    bTest = listArray.DeleteDataByIndex(2);
    //输出所有数据
    listArray.Printf();

    listArray.InsertData(12, 2);
    listArray.InsertData(88, 5);
    listArray.InsertData(8, 9);

    int *pTemp = (int *)malloc(listArray.m_nCurSize * sizeof(int));
    assert(pTemp!=NULL);
    memset(pTemp, 0, listArray.m_nCurSize * sizeof(int));
    memcpy(pTemp, listArray.m_pElem, listArray.m_nCurSize * sizeof(int));

    TRACE("pTemp: Sort before\n");
    TraceData(pTemp, listArray.m_nCurSize);

#if 1
    //排序:直接插入排序算法
    bTest = listArray.StraightInsertionSort(pTemp, listArray.GetCurDataSize());
#endif

#if 1
    //排序:选择排序算法
    bTest = listArray.SelectionSort(pTemp, listArray.GetCurDataSize());
#endif

    TRACE("pTemp: Sort after\n");
    TraceData(pTemp, listArray.m_nCurSize);

    free(pTemp);
    pTemp = NULL;
}

#endif//F_DATA_STRUCT_LINEAR_LIST_ARRAY_20170908_9_44_JHASKDFJHASF_H_


队列

#ifndef F_DATA_STRUCT_QUEUE_20170909_9_15_JHASKDFJHASF_H_
#define F_DATA_STRUCT_QUEUE_20170909_9_15_JHASKDFJHASF_H_

/*
http://blog.csdn.net/juanqinyang/article/details/51354293

队列(queue)是一种采用先进先出(FIFO)策略的抽象数据结构,它的想法来自于生活中排队的策略。
顾客在付款结账的时候,按照到来的先后顺序排队结账,先来的顾客先结账,后来的顾客后结账。
*/

template<class T>
class F_Queue
{
public:
    F_Queue(const int nCapacity = 10);
    ~F_Queue();

    bool IsFull();      //判满
    bool IsEmpty();     //判空
    void CelearQueue(); //清空队列
    int QueueSize();    //队列长度

    bool EnterQueue(const T & tData);   //入队:从队尾增加数据,将队尾索引+1,长度+1
    bool DeleteQueue(T & tData);    //出队:不删除第一个数据,只是将队头的索引+1

    void TraceQueueData();//遍历

public:
    T * m_pData;
    int m_nCurLen;
    int m_nCapacity;
    int m_nHead;
    int m_nTail;
};

template<class T>
F_Queue<T>::F_Queue(const int nCapacity)
: m_nCapacity(nCapacity)
, m_nCurLen(0)
, m_nHead(0)
, m_nTail(0)
{
    if(nCapacity <= 0)
    {
        return;
    }

    m_pData = new T[nCapacity * sizeof(T)];
    if(!m_pData)
    {
        exit(1);
    }
}

template<class T>
F_Queue<T>::~F_Queue()
{
    delete []m_pData;
    m_pData = NULL;
}

//判满
template<class T>
bool F_Queue<T>::IsFull()
{
    return(m_nCurLen == m_nCapacity); 
}

//判空
template<class T>
bool F_Queue<T>::IsEmpty()
{
    return(m_nCurLen == 0);
}

//清空队列
template<class T>
void F_Queue<T>::CelearQueue()
{
    m_nCurLen   = 0;
    m_nHead     = 0;
    m_nTail     = 0;
}

//队列长度
template<class T>
int F_Queue<T>::QueueSize()
{
    return m_nCurLen;
}

//入队
template<class T>
bool F_Queue<T>::EnterQueue(const T & tData)
{
    if(IsFull())
    {
        return false;
    }

    m_pData[m_nTail] = tData;

    m_nTail++;
    m_nTail = m_nTail % m_nCapacity;

    m_nCurLen++;
    return true;
}

//出队
template<class T>
bool F_Queue<T>::DeleteQueue(T & tData)
{
    if(IsEmpty())
    {
        return false;
    }

    tData = m_pData[m_nHead];

    m_nHead++;
    m_nHead = m_nHead % m_nCapacity;

    m_nCurLen--;
    return true;
}

//遍历
template<class T>
void F_Queue<T>::TraceQueueData()
{
    TRACE("\nQueue_Test \n");

    for(int i=m_nHead; i<m_nHead+m_nCurLen; i++)
    {
        TRACE("%d, ", m_pData[i]);
    }

    TRACE("\n\n");
}

void F_Queue_Test()
{
    F_Queue<int> Queue(16);

    //入队
    Queue.EnterQueue(5);
    Queue.EnterQueue(9);
    Queue.EnterQueue(12);
    Queue.EnterQueue(8);
    Queue.EnterQueue(1);
    Queue.EnterQueue(9);
    Queue.TraceQueueData();

    //出队
    int nDelTemp = 0;
    Queue.DeleteQueue(nDelTemp);
    Queue.TraceQueueData();
}

#endif//F_DATA_STRUCT_QUEUE_20170909_9_15_JHASKDFJHASF_H_


队列(链表实现)

#ifndef F_DATA_STRUCTE_QUEUE_LIST_2017_10_10_13_54
#define F_DATA_STRUCTE_QUEUE_LIST_2017_10_10_13_54

/*
数据结构
队列(链表方式实现)
*/

#define SAFE_DELETE(p)\
{\
    if (p)\
    {\
        delete p;\
        p = NULL;\
    }\
}

template<class T>
struct DataType 
{
    DataType *pNext;
    T tData;
};

template<class T>
class F_QueueList 
{
public:
    F_QueueList();
    ~F_QueueList();

    //长度
    int Lenth();

    //判空
    bool IsEmpty();

    //入队
    bool EnterQueue(const T & tData);

    //出队
    bool DeleteQueue(T & tData);

    //打印数据
    void TraceData();

private:
    DataType<T> *m_pTail;
    DataType<T> *m_pHead;

    int m_nSize;
};

template<class T>
F_QueueList<T>::F_QueueList()
: m_pHead(NULL)
, m_pTail(NULL)
, m_nSize(0)
{}

template<class T>
F_QueueList<T>::~F_QueueList()
{
    DataType<T> *pTemp;

    while(m_pHead)
    {
        pTemp = m_pHead->pNext;

        delete m_pHead;
        m_pHead = pTemp;
    }
}

//长度
template<class T>
int F_QueueList<T>::Lenth()
{
    return m_nSize;
}

//判空
template<class T>
bool F_QueueList<T>::IsEmpty()
{
    return m_nSize == 0;
}

//入队
template<class T>
bool F_QueueList<T>::EnterQueue(const T & tData)
{
    DataType<T> *pNode = new DataType<T>;
    if(!pNode)
    {
        return false;
    }

    pNode->tData = tData;
    pNode->pNext = NULL;

    if(0 == m_nSize)
    {
        m_pHead = pNode;
        m_pTail = m_pHead;
    }
    else
    {
        m_pTail->pNext = pNode;

        m_pTail = pNode;
    }

    m_nSize++;

    return true;
}

//出队
template<class T>
bool F_QueueList<T>::DeleteQueue(T & tData)
{
    if(IsEmpty())
    {
        tData = NULL;
        return false;
    }

    tData = m_pHead->tData;

    DataType<T> *pTempNode = m_pHead;

    m_pHead = m_pHead->pNext;
    SAFE_DELETE(pTempNode);

    m_nSize--;
    return true;
}

//打印数据
template<class T>
void F_QueueList<T>::TraceData()
{
    DataType<T> *pTemp = m_pHead;
    while(pTemp)
    {
        TRACE("%d,  ", pTemp->tData);

        pTemp = pTemp->pNext;
    }
}

void F_QueueList_Test()
{
    TRACE("\n队列(链表方式实现)  入队\n");
    F_QueueList<int> QueueData;
    QueueData.EnterQueue(10);
    QueueData.EnterQueue(15);
    QueueData.EnterQueue(14);
    QueueData.EnterQueue(13);
    QueueData.EnterQueue(1);
    QueueData.EnterQueue(2);
    QueueData.EnterQueue(3);
    QueueData.EnterQueue(4);
    QueueData.TraceData();

    TRACE("\n队列(链表方式实现)  出队\n");
    int nData(0);
    QueueData.DeleteQueue(nData);
    QueueData.DeleteQueue(nData);
    QueueData.DeleteQueue(nData);
    QueueData.DeleteQueue(nData);
    QueueData.DeleteQueue(nData);
    QueueData.DeleteQueue(nData);
    QueueData.TraceData();
}
#endif//F_DATA_STRUCTE_QUEUE_LIST_2017_10_10_13_54


二叉树

#ifndef F_DATA_STRUCT_BINARY_TREE_20170920_12_20_JHASKDFJHASF_H_
#define F_DATA_STRUCT_BINARY_TREE_20170920_12_20_JHASKDFJHASF_H_

/*
浅谈数据结构-二叉树
二叉树是树的特殊一种,具有如下特点:
1、每个结点最多有两颗子树,结点的度最大为2。
2、左子树和右子树是有顺序的,次序不能颠倒。
3、即使某结点只有一个子树,也要区分左右子树。

满二叉树, 完全二叉树, 非完全二叉树

http://www.cnblogs.com/polly333/p/4740355.html

http://www.cnblogs.com/enjoyall/p/6024657.html

*/

/*
C语言实现
*/

template<class T>
struct BinaryTreeNode_
{
    T tData;

    BinaryTreeNode_<T> *pLeftTreeNode;
    BinaryTreeNode_<T> *pRightTreeNode;
};

//先序遍历二叉树(递归)
template<class T>
void PreOrder(BinaryTreeNode_<T> *pNode)
{
    if(pNode)
    {
        cout << pNode->tData <<", ";

        PreOrder(pNode->pLeftTreeNode);
        PreOrder(pNode->pRightTreeNode);
    }
};

//先序遍历二叉树(递归)
template<class T>
void InOrder(BinaryTreeNode_<T> *pNode)
{
    if(pNode)
    {
        InOrder(pNode->pLeftTreeNode);

        cout << pNode->tData <<", ";

        InOrder(pNode->pRightTreeNode);
    }
};

//后序遍历二叉树(递归)
template<class T>
void AfterOrder(BinaryTreeNode_<T> *pNode)
{
    if(pNode)
    {
        AfterOrder(pNode->pLeftTreeNode);
        AfterOrder(pNode->pRightTreeNode);

        cout << pNode->tData <<", ";
    }
};

//创建二叉树
template<class T>
void CreatBiTree(BinaryTreeNode_<T> *&pNode)
{
    BinaryTreeNode_<T>* p = pNode;

    T tData;
    cin>>tData;

    if(tData == -1)
    {
        pNode = NULL;
    }
    else
    {
        pNode = new BinaryTreeNode_<T>();

        pNode->tData = tData;
        CreatBiTree(pNode->pLeftTreeNode);
        CreatBiTree(pNode->pRightTreeNode);
    }
}

void F_Binary_Test()
{
    BinaryTreeNode_<int> *pRoot = NULL;

    //创建二叉树
    cout <<"创建二叉树, 以-1结束结点" <<endl;
    CreatBiTree(pRoot);

    //先序遍历二叉树
    cout <<"先序遍历二叉树" <<endl;
    PreOrder(pRoot);
}

#endif//F_DATA_STRUCT_BINARY_TREE_20170920_12_20_JHASKDFJHASF_H_


堆栈

#ifndef F_DATA_STRUCT_STACK_20170923_16_15_JHASKDFJHASF_H_
#define F_DATA_STRUCT_STACK_20170923_16_15_JHASKDFJHASF_H_

/*
堆栈(Stack)是一种特殊的线性表。
1. 后进先出( last-in-first-out, LIFO)的数据结构
2. 插入 和 删除 操作都在表的同一端进行。其中一端被称为栈顶(top),另一端被称为栈底(bottom)。
3. 堆栈数据对象的实例 也是 线性表数据对象的实例
4. 栈顶元素存储在element[length-1]中,栈底元素存储在element[0]中
5. 只操作栈顶元素,即后进先出
*/

#if 1
/*
堆栈数据对象的实例 也是 线性表数据对象的实例
因此 堆栈 可以从 ListArrayBase 继承而来
*/

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"

using namespace std;

const int N_ARRAY_BASE_INIT_SIZE = 10;  //初始化分配空间的大小
const int N_ARRAY_BASE_INCREMENT = 10;  //每次分配空间的增量

enum E_StatusBase
{
    STATUS_ERROR_BASE   = -1,
    STATUS_SUC_BASE     = 1
};

template<class T>
void TraceDataBase(const T &pData, int nDataSize)
{
    for (int i=0; i<nDataSize; i++)
    {
        TRACE("%d  ", pData[i]);
    }

    TRACE("\n");
}

//线性表的数组类,即为堆栈的基类
template<class T>
class ListArrayBase
{
public:
    ListArrayBase(int nNewSize = 10);
    ~ListArrayBase();

    //! 根据索引, 插入数据
    int InsertData(const T &eData, const int nInserIndex);

    //! 输出所有数据
    void Printf();

    //! 根据索引,获取当前数据
    bool GetDataByIndex(T &eData, const int nIndex);

    //! 根据数据,获取当前数据的索引
    bool GetIndexByData(const T &eData, int &nIndex);

    //! 获取当前数据个数
    int GetCurDataSize();

    //! 判断是否为空
    bool IsEmpty();

    //! 根据索引,删除数据,并将后面的数据前移
    bool DeleteDataByIndex(const int nIndex);

    //! 排序:直接插入排序算法
    bool StraightInsertionSort(T *pData, const int nSize);

    //! 排序:选择排序算法
    bool SelectionSort(T *pData, const int nSize);

    //获取数据
    T *GetData();

private:
    T *m_pElem;         //存数据基地址
    int m_nCurSize;     //当前大小
    int m_nTotalSize;   //容量
};

template<class T>
ListArrayBase<T>::ListArrayBase(int nNewSize)
:m_nCurSize(0)
,m_nTotalSize(0)
{
    if(nNewSize <= 0)
    {
        return;
    }

    m_pElem = (T *)malloc(nNewSize * sizeof(T));
    if (!m_pElem)
    {
        return ;
    }

    m_nCurSize      = 0;
    m_nTotalSize    = nNewSize;
}

template<class T>
ListArrayBase<T>::~ListArrayBase()
{
    free(m_pElem);
    m_pElem = NULL;
}

//根据索引, 插入数据
template<class T>
int ListArrayBase<T>::InsertData(const T &eData, const int nInserIndex)
{
    if ((nInserIndex<0) || (nInserIndex > m_nCurSize))
    {
        return STATUS_ERROR_BASE;
    }

    //内存空间不够,重新分配新内存
    if(m_nTotalSize <= m_nCurSize)
    {
        T *pNewArray = (T*)realloc(m_pElem, (m_nTotalSize + N_ARRAY_BASE_INCREMENT) * sizeof(T));
        if (!pNewArray)
        {
            return STATUS_ERROR_BASE;
        }

        m_pElem = pNewArray;
        m_nTotalSize += N_ARRAY_BASE_INCREMENT;
    }

    T *pInsertE = &m_pElem[nInserIndex];

    //将插入索引后面的数据后移一个位置
    T *pMoveE;
    for(pMoveE=&m_pElem[m_nCurSize]; pMoveE>=pInsertE; pMoveE--)
    {
        int nData =  *(pMoveE-1);
        *pMoveE = *(pMoveE-1);
    }

    *pInsertE = eData;
    m_nCurSize += 1;

    return STATUS_SUC_BASE;
}

//输出所有数据
template<class T>
void ListArrayBase<T>::Printf()
{
    T eData = 0;
    for (int i=0; i<m_nCurSize; i++)
    {
        eData = m_pElem[i];
        cout <<eData;
        printf("%d /n", eData);
    }
}

//根据索引,获取当前数据
template<class T>
bool ListArrayBase<T>::GetDataByIndex(T &eData, const int nIndex)
{
    if((nIndex<0) || (nIndex>=m_nCurSize))
    {
        return false;
    }

    eData = m_pElem[nIndex];

    return true;
}

//根据数据,获取当前数据的索引
template<class T>
bool ListArrayBase<T>::GetIndexByData(const T &eData, int &nIndex)
{
    nIndex = -1;

    for(int i=0; i<m_nCurSize; i++)
    {
        if (m_pElem[i] == eData)
        {
            nIndex = i;
            break;
        }
    }

    return nIndex >= 0 ? true : false;
}

//获取当前数据个数
template<class T>
int ListArrayBase<T>::GetCurDataSize()
{
    return m_nCurSize;
}

template<class T>
T *ListArrayBase<T>::GetData()
{
    if (IsEmpty())
    {
        return NULL;
    }

    return m_pElem;
}

//判断是否为空
template<class T>
bool ListArrayBase<T>::IsEmpty()
{
    return m_nCurSize == 0 ? true : false;
}

//根据索引,删除数据,并将后面的数据前移
template<class T>
bool ListArrayBase<T>::DeleteDataByIndex(const int nIndex)
{
    if((nIndex < 0) || (nIndex>m_nCurSize))
    {
        return false;
    }

    for (int i=0; i<m_nCurSize; i++)
    {
        if (i>=nIndex)
        {
            m_pElem[i] = m_pElem[i+1];
        }
    }

    m_nCurSize--;
    return true;
}

//排序:直接插入排序算法
template<class T>
bool ListArrayBase<T>::StraightInsertionSort(T *pData, const int nSize)
{
    if (nSize <= 1)
    {
        return false;
    }

    TRACE("排序:直接插入排序算法\n");

    T nCurTempDataI(0);
    for (int i=1; i<nSize; i++)
    {
        nCurTempDataI = pData[i];

        for (int j=i-1; j>=0; j--)
        {
            if (nCurTempDataI <= pData[j])
            {
                pData[j+1]  = pData[j+1] + pData[j];
                pData[j]    = pData[j+1] - pData[j];
                pData[j+1]  = pData[j+1] - pData[j];
            }
        }

        TraceDataBase(pData, nSize);
    }

    return true;
}

//排序:选择排序算法
template<class T>
bool ListArrayBase<T>::SelectionSort(T *pData, const int nSize)
{
    if (nSize <= 1)
    {
        return false;
    }

    TRACE("排序:选择排序算法\n");

    int nMinIndex(0);
    for(int i=0; i<nSize-1; i++)
    {   
        for(int j=i+1; j<nSize; j++)
        {
            if (pData[nMinIndex] >= pData[j])
            {
                nMinIndex = j;
            }
        }

        if (pData[i] != pData[nMinIndex])
        {
            pData[i] = pData[i] + pData[nMinIndex]; 
            pData[nMinIndex] = pData[i] - pData[nMinIndex]; 
            pData[i] = pData[i] - pData[nMinIndex]; 
        }

        TraceDataBase(pData, nSize);
    }

    return true;
}

template<class T>
class F_DataStructeStack : private ListArrayBase<T>
{
public:
    F_DataStructeStack(const int nMaxSize)
    :ListArrayBase(nMaxSize)
    {}

    //获取栈数据
    T GetTopData()
    {
        if (ListArrayBase::IsEmpty())
        {
            return NULL;
        }

        return m_pElem[m_nCurSize-1];
    }

    //! 判断是否为空
    bool IsEmpty()
    {
        return ListArrayBase::IsEmpty();
    }

    //获取数据
    T* GetData()
    {
        return ListArrayBase::GetData();
    }

    //! 获取当前数据个数
    int GetCurDataSize()
    {
        return ListArrayBase::GetCurDataSize();
    }

    //增加数据
    F_DataStructeStack<T> &AddData(const T tData)
    {
        ListArrayBase::InsertData(tData, GetCurDataSize());

        return *this;
    }

    //删除数据
    F_DataStructeStack<T> &DeleteData()
    {
        ListArrayBase::DeleteDataByIndex(GetCurDataSize());

        return *this;
    }
};

void F_DataStructeStack_Test()
{
    F_DataStructeStack<int> pData(N_ARRAY_BASE_INIT_SIZE);

    bool bEmpty = pData.IsEmpty();

    for (int i=0; i<10; i++)
    {
        pData.AddData(i*2);
    }

    pData.AddData(88);

    for (int i=0; i<10; i++)
    {
        pData.AddData(i*2);
    }

    TRACE("\DataStructe: Stack, AddData after\n");
    TraceDataBase(pData.GetData(), pData.GetCurDataSize());

    pData.DeleteData();
    TRACE("\DataStructe: Stack, DeleteData after\n");
    TraceDataBase(pData.GetData(), pData.GetCurDataSize());

    bEmpty = pData.IsEmpty();
}

#endif

#endif//F_DATA_STRUCT_STACK_20170923_16_15_JHASKDFJHASF_H_


链表描述

#ifndef F_DATA_STRUCT_LIST_CHAIN_20170927_13_51_JHASKDFJHASF_H_
#define F_DATA_STRUCT_LIST_CHAIN_20170927_13_51_JHASKDFJHASF_H_

/*
链表描述
类ChainNode 和ListChain
在链表描述中,数据对象实例的每个元素都放在单元或节点中进行描述。
不过,节点不必是一个数组元素,因此没有什么公式可用来定位某个元素。
取而代之的是,每个节点中都包含了与该节点相关的其他节点的位置信息
*/

#if 1

template <class T>
class ChainNode 
{
public:
    T tData;
    ChainNode<T> *pNextLink;
};

template<class T>
class ListChain 
{
public :
    ListChain();

    ~ListChain();

    //链表是否为空
    bool IsEmpty() const;

    //链表长度
    int Length() const;

    //根据 索引 查找 数据
    bool FindDataByIndex(int nIndex, T& tData) const;

    //根据 数据 查找 索引
    int SearchIndexByData(const T& tData) const;

    //根据 索引 删除 数据
    ListChain<T>& DeleteDataByIndex(int nIndex, T& tData);

    //根据 索引 插入 数据
    ListChain<T>& InsertDataByIndex(int nIndex, const T& tData);

    //在链表尾部增加数据
    ListChain<T>& PushBack(const T& tData);

    //打印数据
    void TraceData();

public:
    ChainNode<T> *m_pFirstNode; // 指向第一个节点的指针
};

template<class T>
ListChain<T>::ListChain()
:m_pFirstNode(0)
{}

template<class T>
ListChain<T>::~ListChain()
{
    ChainNode<T> *pTempFirstNode;

    while (m_pFirstNode)
    {
        pTempFirstNode = m_pFirstNode->pNextLink;

        delete m_pFirstNode;
        m_pFirstNode = pTempFirstNode;
    }
}

//链表是否为空
template<class T>
bool ListChain<T>::IsEmpty() const
{
    return m_pFirstNode == 0;
}

//链表长度
template<class T>
int ListChain<T>::Length() const
{
    int nSize(0);

    ChainNode<T> *pCurNode = m_pFirstNode;

    while (pCurNode)
    {
        nSize++;

        pCurNode = pCurNode->pNextLink;
    }

    return nSize;
}

//根据 索引 查找 数据
template<class T>
bool ListChain<T>::FindDataByIndex(int nIndex, T& tData) const
{
    if(IsEmpty() || nIndex <1)
    {
        return false;
    }

    int nCurIndex(1);
    ChainNode<T> *pCurNode = m_pFirstNode;

    while((nCurIndex <= nIndex) && pCurNode)
    {
        pCurNode = pCurNode->pNextLink;

        nCurIndex++;
    }

    if(pCurNode)
    {
        tData = pCurNode->tData;
    }

    return true;
}

//根据 数据 查找 索引
template<class T>
int ListChain<T>::SearchIndexByData(const T& tData) const
{
    int nIndex(-1);

    ChainNode<T> *pCurNode = m_pFirstNode;

    while (pCurNode)
    {
        nIndex++;

        if (tData == pCurNode->tData)
        {
            return nIndex;
        }

        pCurNode = pCurNode->pNextLink;
    }

    return -1;
}

//根据 索引 插入 数据
template<class T>
ListChain<T>& ListChain<T>::InsertDataByIndex(int nIndex, const T& tData)
{
    if(nIndex < 0)
    {
        return *this;
    }

    ChainNode<T> *pNode = m_pFirstNode;
    ChainNode<T> *pNewNode = new ChainNode<T>;
    if(!pNewNode)
    {
        return *this;
    }
    pNewNode->tData = tData;

    //从开始位置插入元素
    if (0 == nIndex)
    {
        pNewNode->pNextLink = pNode;

        m_pFirstNode = pNewNode;
    }
    else
    {
        //找到插入数据的节点位置
        int nCurIndex(1);
        while(pNode && (nCurIndex < nIndex))
        {
            pNode = pNode->pNextLink;

            nCurIndex++;
        }

        pNewNode->pNextLink = pNode->pNextLink;
        pNode->pNextLink = pNewNode;
    }

    return *this;
}

//在链表尾部增加数据
template<class T>
ListChain<T>& ListChain<T>::PushBack(const T& tData)
{
    ChainNode<T> *pNodeNew = new ChainNode<T>;
    if (!pNodeNew)
    {
        return *this;
    }

    int nEndIndex(0);

    //找到末尾位置的索引
    if(m_pFirstNode)
    {
        ChainNode<T> *pNode = m_pFirstNode;

        while(pNode)
        {
            pNode = pNode->pNextLink;
            nEndIndex++;
        }
    }

    //从末尾位置的索引插入数据
    InsertDataByIndex(nEndIndex, tData);

    return *this;
}

//打印数据
template<class T>
void ListChain<T>::TraceData()
{
    TRACE("\n单向链表数据打印\n");

    ChainNode<T> *pNode = m_pFirstNode;

    while(pNode)
    {
        TRACE("%d,  ", pNode->tData);

        pNode = pNode->pNextLink;
    }
}

//根据 索引 删除 数据
template<class T>
ListChain<T>& ListChain<T>::DeleteDataByIndex(int nIndex, T& tData)
{
    if (nIndex<0 || !m_pFirstNode)
    {
        return *this;
    }

    ChainNode<T> *pCurNode = m_pFirstNode;

    if(0 == nIndex)
    {
        tData = m_pFirstNode->tData;
        m_pFirstNode = m_pFirstNode->pNextLink;

        delete pCurNode;
        pCurNode = NULL;
    }
    else
    {
        //找到删除数据的上一个节点位置
        int nCurIndex(1);
        while(pCurNode && (nCurIndex < nIndex))
        {
            pCurNode = pCurNode->pNextLink;

            nCurIndex++;
        }

        ChainNode<T> *pDeleteNode;
        pDeleteNode = pCurNode->pNextLink;
        pCurNode->pNextLink = pDeleteNode->pNextLink;

        delete pDeleteNode;
        pDeleteNode = NULL;
    }

    return *this;
}

//链表描述
void F_DataStructeListChain_Test()
{
    ListChain<int> listChain;

    //从头部插入数据
    listChain.InsertDataByIndex(0, 9);
    listChain.InsertDataByIndex(0, 8);
    listChain.InsertDataByIndex(0, 5);
    listChain.InsertDataByIndex(0, 6);
    listChain.InsertDataByIndex(0, 7);
    listChain.TraceData();

    //从中部插入数据
    listChain.InsertDataByIndex(2, 22);
    listChain.TraceData();

    //从尾部插入
    listChain.PushBack(10);
    listChain.PushBack(14);
    listChain.PushBack(11);
    listChain.TraceData();

    //查找索引
    int nTemp = listChain.SearchIndexByData(7);

    //查找数据
    int nDtata(0);
    listChain.FindDataByIndex(10, nDtata);

    //将头部数据删除
    listChain.DeleteDataByIndex(0, nDtata);
    listChain.TraceData();

    //将中部数据删除
    listChain.DeleteDataByIndex(3, nDtata);
    listChain.TraceData();
    listChain.DeleteDataByIndex(5, nDtata);
    listChain.TraceData();

    //将尾部数据删除
    listChain.DeleteDataByIndex(listChain.Length()-1, nDtata);
    listChain.TraceData();
}

#endif

#endif//F_DATA_STRUCT_LIST_CHAIN_20170927_13_51_JHASKDFJHASF_H_
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值