数据:被计算机识别、处理的描述事物的符号集合。
数据项:数据不可分割的最小单位。
数据元素:有一定意义的基本单位,如某个对象。
数据对象:性质相同的数据元素的集合,如数组。
数据结构:相互之间存在一种或多种关系的数据元素集合。
逻辑结构:
- 集合结构
- 线性结构
- 树形结构
- 图形结构
物理结构:
- 顺序存储结构
- 链式存储结构
算法:解决特定问题的步骤。
特性:
- 0或多个输入,必须有1个或多个输出;
- 有穷性,且时间可接受;
- 确定性,无二义;
- 可行性,可通过已有的运算执行有限次实现。
评判标准:
- 正确
- 可读
- 健壮
- 时间、空间(矛盾)
抽象数据类型
数据类型分为:
- 原子类型:不可分割
- 结构类型:可分割
ADT list
DATA
描述
Operation
初始化。。。
endADT
时间复杂度
O(1)<O(log_n)<O(N)<O(nlog_n)
<O(n^2)<O(n^3)<O(2^n)
<O(n!)<O(n^n)
线性表
如字符串、数组。
顺序存储和链式存储的区别:是否连续。
顺序表的插入数据是怎么实现的,删除数据是怎么实现的? 将之后的元素后/前移。
怎么检测顺序表的堆空间够不够用? 不够用怎么扩充空间? 判断当前元素个数是否等与最大个数。
链表中的节点是怎么串联起来的:指针
怎么遍历出链表中的所有节点:
链表中删除数据的原理是什么?
顺序表
#include <iostream>
/*
Date: 2019/8/15
Author: starr
*/
/*
ADT ArrayList
Data
Template data type.
Pointer to buf initialized to nullptr.
Length currently and max value.
Operation:
Insert data;
Delete data;
Get size;
Get index of any data;
Get data of any index;
Check if it's empty;
Modify data of any index.
*/
template <typename T>
class ArrayList
{
private:
T *m_pBuf;
size_t m_nCurLen;
size_t m_nMaxLen;
public:
ArrayList() :m_pBuf(nullptr), m_nCurLen(0), m_nMaxLen(0) {}
~ArrayList()
{
clear();
}
/*
Func name:
Description:
Parameters:
Return:
*/
bool insert(size_t index, const T& data);
void resize(size_t size);
bool remove(size_t index, T* pOld = nullptr);
size_t size() const { return m_nCurLen; }
bool isEmpty() const { return m_nCurLen == 0; }
size_t index(const T& data) const;
T& get(size_t index) const;
T& operator[](size_t index)
{
return get(index);
}
void clear()
{
delete[] m_pBuf;
m_nCurLen = m_nMaxLen = 0;
}
template<typename T>
friend std::ostream& operator<< (std::ostream& out, const ArrayList<T>& arr);
void push_back(const T& data)
{
insert(m_nCurLen, data);
}
T pop_back()
{
T old;
if (isEmpty())
{
throw std::exception("ArrayList is empty");
}
remove(m_nCurLen - 1, &old);
return old;
}
};
template<typename T>
bool ArrayList<T>::insert(size_t index, const T& data)
{
// Param checking.
if (index < 0 || index > m_nCurLen) return false;
if (m_nCurLen == m_nMaxLen)
{
resize((m_nMaxLen + 1) * 2);
}
memmove(m_pBuf + index + 1,
m_pBuf + index,
sizeof(T) * (m_nCurLen - index) );
m_pBuf[index] = data;
++m_nCurLen;
return true;
}
template<typename T>
void ArrayList<T>::resize(size_t size)
{
if (m_pBuf == nullptr)
{
m_pBuf = new T[size];
m_nMaxLen = size;
}
else
{
T* pNewBuf = new T[size];
memcpy(pNewBuf,m_pBuf,
(size > m_nMaxLen ? m_nMaxLen : size) * sizeof(T));
delete[] m_pBuf;
m_pBuf = pNewBuf;
m_nMaxLen = size;
}
}
template<typename T>
bool ArrayList<T>::remove(size_t index, T* pOld = nullptr)
{
if (index < 0 || index > m_nCurLen)
{
return false;
}
if (pOld != nullptr)
{
*pOld = m_pBuf[index];
}
memmove(m_pBuf + index,
m_pBuf + index + 1,
sizeof(T) * (m_nCurLen - index - 1));
--m_nCurLen;
return true;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const ArrayList<T>& arr)
{
out << "[";
for (size_t i = 0; i < arr.m_nCurLen; ++i)
{
out << arr.m_pBuf[i];
out << ",";
}
out << "]";
return out;
}
template<typename T>
size_t ArrayList<T>::index(const T& data) const
{
for (int i = 0; i < m_nCurLen; ++i) {
if (m_pBuff[i] == data) {
return i;
}
}
return -1;
}
template<typename T>
T& ArrayList<T>::get(size_t index) const
{
if (index < 0 || index > m_nCurLen)
{
throw std::exception("index out of bound");
}
return m_pBuf[index];
}
int main()
{
ArrayList<int> arr;
arr.insert(0, 1);
arr.insert(0, 2);
arr.insert(0, 3);
try
{
std::cout << arr.get(1) << std::endl;
std::cout << arr.get(-1) << std::endl;
}
catch (std::exception e)
{
std::cout << e.what() << std::endl;
}
std::cout << arr << std::endl;
arr.remove(2);
arr.remove(0);
arr.remove(0);
return 0;
}
链表
#include <iostream>
template<typename T>
class Node
{
public:
T m_data;
Node* m_pNext;
Node(const T& data) : m_data(data), m_pNext(nullptr) {}
};
template<typename T>
/*
The member m_pHead doesn't store data, while just pointing to the first node.
*/
class LinkList
{
private:
Node<T>* m_pHead;
size_t m_nLen;
public:
LinkList() :m_pHead(nullptr), m_nLen(0) {}
~LinkList()
{
clear();
}
void clear();
bool insert(size_t index,const T& data);
bool remove(size_t index,T* pOlddata);
size_t size() const{ return m_nLen; }
bool isEmpty() const{ return m_nLen == 0; }
void push_back(const T& data) { insert(m_nLen, data); }
T pop_back()
{
T data;
if (m_nLen == 0)
{
throw std::exception("List is empty.");
}
remove(m_nLen - 1, &data);
return node;
}
template <typename T>
friend std::ostream& operator<<(std::ostream& out, const LinkList<T>& list);
};
template<typename T>
bool LinkList<T>::insert(size_t index, const T& data)
{
if (index < 0 || index > m_nLen)
{
return false;
}
Node<T>* pNewNode = new Node<T>(data);
if (m_pHead == nullptr)
{
m_pHead = new Node<T>(0);
m_pHead->m_pNext = pNewNode;
}
else
{
Node<T> *pPre = m_pHead;
for (size_t i = 0; i < index ; ++i)
{
pPre = pPre->m_pNext;
}
pNewNode->m_pNext = pPre->m_pNext;
pPre->m_pNext = pNewNode;
}
++m_nLen;
return true;
}
template<typename T>
bool LinkList<T>::remove(size_t index, T* pOlddata)
{
if (index < 0 || index > m_nLen)
{
return false;
}
if (m_pHead->m_pNext == nullptr)
{
throw std::exception("List is empty.");
}
Node<T> *pPre = m_pHead,*pCur = m_pHead->m_pNext;
for (size_t i = 0; i < index; ++i)
{
pPre = pCur;
pCur = pCur->m_pNext;
}
pPre->m_pNext = pCur->m_pNext;
delete pCur;
*pOlddata = pCur->m_data;
--m_nLen;
return true;
}
template<typename T>
void LinkList<T>::clear()
{
while (m_pHead->m_pNext)
{
Node<T> *pDel = m_pHead->m_pNext;
m_pHead->m_pNext = pDel->m_pNext;
delete pDel;
}
m_nLen = 0;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const LinkList<T>& list)
{
if (list.isEmpty())
{
out << "[]" << std::endl;
}
out << "[";
for (Node<T> *pCur = list.m_pHead->m_pNext; pCur; pCur = pCur->m_pNext)
{
out << pCur->m_data;
out << ",";
}
out << "\b]" << std::endl;
return out;
}
int main()
{
LinkList<int> list;
list.insert(0, 10);
list.insert(0, 11);
list.insert(2, 12);
list.insert(1, 13);
std::cout << list << std::endl;
int oldData = 0;
list.remove(1, &oldData);
list.remove(0, &oldData);
list.remove(1, &oldData);
return 0;
}