1.链表
这是单链表
链表大全
链表代码
点击查看代码
#include<stdio.h>
#include<Windows.h>
#define SUCCESS 1 // 执行成功
#define ERROR -1 // 执行失败
#define INDEX_IS_ERROR -2 // 错误的索引号
#define BUFFER_IS_EMPTY -3 // 缓冲区已空
template<class T_ELE>
class NODE
{
public:
T_ELE Data;
NODE<T_ELE>* pNext;
};
template <class T_ELE>
class LinkedList :public NODE<T_ELE>
{
public:
LinkedList(); //默认构造函数
~LinkedList();
public:
BOOL IsEmpty(); //判断链表是否为空 空返回1 非空返回0
DWORD Clear(); //清空链表
DWORD GetElement(IN DWORD dwIndex, OUT T_ELE& Element); //根据索引获取元素
DWORD GetElementIndex(IN T_ELE& Element); //根据元素获取链表中的索引
DWORD Insert(IN T_ELE Element); //新增元素
DWORD Insert(IN DWORD dwIndex, IN T_ELE Element); //根据索引新增元素
DWORD Delete(IN DWORD dwIndex); //根据索引删除元素
DWORD GetSize(); //获取链表中元素的数量
VOID Show();
private:
NODE<T_ELE>* m_head; //链表头指针,指向第一个节点
DWORD m_dwLength; //元素的数量
};
//无参构造函数 初始化成员
template<class T_ELE> LinkedList<T_ELE>::LinkedList()
:m_head(NULL), m_dwLength(0)
{
}
//析构函数 清空元素
template<class T_ELE> LinkedList<T_ELE>::~LinkedList()
{
Clear();
}
//判断链表是否为空
template<class T_ELE> BOOL LinkedList<T_ELE>::IsEmpty()
{
if (m_head == NULL || m_dwLength == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
//清空链表
template<class T_ELE> DWORD LinkedList<T_ELE>::Clear()
{
// 1. 判断链表是否为空
if (m_head == NULL || m_dwLength == 0)
{
return BUFFER_IS_EMPTY;
}
// 2. 循环删除链表中的节点
NODE<T_ELE>* pTempNode = m_head;
for (DWORD i = 0; i < m_dwLength; i++)
{
NODE<T_ELE>* pIterator = pTempNode;
pTempNode = pTempNode->pNext;
delete pIterator;
}
// 3. 删除最后一个节点并将链表长度置为0
m_head = NULL;
m_dwLength = 0;
return SUCCESS;
}
//根据索引获取元素
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElement(IN DWORD dwIndex, OUT T_ELE& Element)
{
NODE<T_ELE>* pTempNode = NULL;
// 1. 判断索引是否有效
if (dwIndex<0 || dwIndex>m_dwLength)
{
return INDEX_IS_ERROR;
}
// 2. 取得索引指向的节点
pTempNode = m_head;
for (DWORD i = 0; i < dwIndex; i++)
{
pTempNode = pTempNode->pNext;
}
// 3. 将索引指向节点的值复制到OUT参数
memcpy(&Element, &pTempNode->Data, sizeof(T_ELE));
return SUCCESS;
}
//根据元素内容获取索引
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElementIndex(IN T_ELE& Element)
{
NODE<T_ELE>* pTempNode = NULL;
// 1. 判断链表是否为空
if (m_head == NULL || m_dwLength == 0)
{
return INDEX_IS_ERROR;
}
// 2. 循环遍历链表,找到与Element相同的元素
pTempNode = m_head;
for (DWORD i = 0; i < m_dwLength; i++)
{
if (!memcmp(&Element, &pTempNode->Data, sizeof(T_ELE)))
{
return i;
}
pTempNode = pTempNode->pNext;
}
return ERROR;
}
//在链表尾部新增节点
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN T_ELE Element)
{
NODE<T_ELE>* pNewNode = new NODE<T_ELE>;
memset(pNewNode, 0, sizeof(NODE<T_ELE>));
memcpy(&pNewNode->Data, &Element, sizeof(T_ELE));
// 1. 判断链表是否为空
if (m_head == NULL || m_dwLength == 0)
{
m_head = pNewNode;
m_dwLength++;
return SUCCESS;
}
// 2. 如果链表中已经有元素
NODE<T_ELE>* pTempNode = m_head;
for (DWORD i = 0; i < m_dwLength - 1; i++)
{
pTempNode = pTempNode->pNext;
}
pTempNode->pNext = pNewNode;
m_dwLength++;
return SUCCESS;
}
//将节点新增到指定索引的位置 0 1 2 3 4
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN DWORD dwIndex, IN T_ELE Element)
{
NODE<T_ELE>* pPreviousNode = NULL;
NODE<T_ELE>* pCurrentNode = NULL;
NODE<T_ELE>* pNextNode = NULL;
NODE<T_ELE>* pNewNode = new NODE<T_ELE>;
memset(pNewNode, 0, sizeof(NODE<T_ELE>));
memcpy(&pNewNode->Data, &Element, sizeof(T_ELE));
// 1. 判断链表是否为空
if (m_head == NULL || m_dwLength == 0)
{
if (dwIndex == 0)
{
m_head = pNewNode;
m_dwLength++;
return SUCCESS;
}
return BUFFER_IS_EMPTY;
}
// 2. 判断索引值是否有效
if (dwIndex<0 || dwIndex>m_dwLength)
{
return INDEX_IS_ERROR;
}
// 3. 如果索引为0
if (dwIndex == 0)
{
pNewNode->pNext = m_head;
m_head = pNewNode;
m_dwLength++;
return SUCCESS;
}
// 4. 如果索引为链表尾
if (dwIndex == m_dwLength)
{
pCurrentNode = m_head;
for (DWORD i = 0; i < dwIndex - 1; i++)
{
pCurrentNode = pCurrentNode->pNext;
}
pCurrentNode->pNext = pNewNode;
m_dwLength++;
return SUCCESS;
}
// 5. 如果索引为链表中
pCurrentNode = m_head;
for (DWORD i = 0; i < dwIndex - 1; i++)
{
pCurrentNode = pCurrentNode->pNext;
}
pNextNode = pCurrentNode->pNext;
pCurrentNode->pNext = pNewNode;
pNewNode->pNext = pNextNode;
m_dwLength++;
return SUCCESS;
}
//根据索引删除节点
template<class T_ELE> DWORD LinkedList<T_ELE>::Delete(IN DWORD dwIndex)
{
NODE<T_ELE>* pPreviousNode = NULL;
NODE<T_ELE>* pCurrentNode = NULL;
NODE<T_ELE>* pNextNode = NULL;
// 1. 判断链表是否为空
if (m_head == NULL || m_dwLength == 0)
{
return BUFFER_IS_EMPTY;
}
// 2. 判断索引值是否有效
if (dwIndex<0 || dwIndex>m_dwLength)
{
return INDEX_IS_ERROR;
}
// 3. 如果链表中只有头节点,且要删除头节点
if (m_dwLength == 1 && dwIndex == 0)
{
delete m_head;
m_head = NULL;
m_dwLength--;
return SUCCESS;
}
// 4. 如果要删除头节点
if (dwIndex == 0)
{
pNextNode = m_head->pNext;
delete m_head;
m_head = pNextNode;
m_dwLength--;
return SUCCESS;
}
// 5. 如果是其他情况
pPreviousNode = m_head;
for (DWORD i = 0; i < dwIndex - 1; i++)
{
pPreviousNode = pPreviousNode->pNext;
}
pCurrentNode = pPreviousNode->pNext;
pNextNode = pCurrentNode->pNext;
pPreviousNode->pNext = pNextNode;
delete pCurrentNode;
m_dwLength--;
return SUCCESS;
}
//获取链表中节点的数量
template<class T_ELE> DWORD LinkedList<T_ELE>::GetSize()
{
if (m_head == NULL || m_dwLength == 0)
{
return BUFFER_IS_EMPTY;
}
else
{
return m_dwLength;
}
}
template<class T_ELE> VOID LinkedList<T_ELE>::Show()
{
if (m_head == NULL || m_dwLength == 0)
{
printf("Linklist is empty.\n");
return;
}
NODE<T_ELE>* pTempNode = m_head;
for (DWORD i = 0; i < m_dwLength; i++)
{
printf("pNode->data: %d\n", pTempNode->Data);
pTempNode = pTempNode->pNext;
}
}
VOID TestLink()
{
LinkedList<int> Link;
int index = 4;
int value = 0;
int element = 10;
Link.Insert(0, 9);
Link.Insert(1);
printf("Link.GetElementIndex(%d): %d\n", element, Link.GetElementIndex(element));
Link.Insert(1, 8);
Link.Insert(2);
printf("Link.GetSize(): %d\n", Link.GetSize());
Link.Insert(3);
Link.GetElement(index, value);
printf("Link.GetElement(%d, %d)\n", index, value);
Link.Delete(1);
Link.Delete(0);
Link.Delete(2);
printf("Link.GetSize(): %d\n", Link.GetSize());
Link.Insert(1);
Link.Show();
Link.Clear();
Link.Show();
}
int main()
{
TestLink();
return 0;
}
二叉树
1.二叉树性质
根节点
父节点
字节点
左子树
右子树
这些性质是相对而言
2.二叉树的高度
二叉树的高度也是相对而言 图中的高度为5
3.二叉树的遍历
前序遍历:(根 左 右)
1 2 4 6 7 3 5
中序遍历:(左 根 右)
对于当前结点,先输出它的左孩子,然后输出该结点,最后输出它的右孩子。以上图为例:
左树 为 2 开始遍历 4 -6-7 -2 左树遍历完成
根 1
3-的左节点 为5
右 5-3
4.后序遍历
左右根
7-6-4-2
5-3
1
遍历代码
https://img-blog.csdnimg.cn/d39c11182d0f485f8e3d194fe4c8340e.png
前
A B D E G C F
中
左
B-D D左右树为空 输出 D
回B B左树为空 输出B
E-G 左节点为 G 根为 E
D B G E
左树遍历完成
根 A
C无左树 输出C F
DBGEACF
后序排列
B -D -D
B-E-G G E
D G E B
C-F F C
A
D G E B F C A
查找代码
点击查看代码