2.13 --2.20 鏈表 雙叉樹

1.鏈表
image
這是單鏈表
鏈表大全
image
鏈表代碼

點擊查看代碼
#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;
}

二叉樹
image
1.二叉樹性質
根節點
父節點
字節點
左子樹
右子樹
這些性質是相對而言
2.二叉樹的高度
image
二叉樹的高度也是相對而言 圖中的高度爲5
3.二叉樹的遍歷
image
前序遍歷:(根 左 右)
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
查找代碼

點擊查看代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章