//My_list.h

class CMy_list
{
public:
	CMy_list();
	~CMy_list();

	//链表元素
	typedef struct _LIST_NODE
	{
		int nData;            //数据
		_LIST_NODE* pNext;    //下一个数据的地址
	}LIST_NODE, *PLIST_NODE;

public:
	bool push_front(int nElement);             //添加到头部
	bool push_back(int nElement);              //添加到尾部
	bool pop_back(int* pElement = 0);          //删除最后一个元素
	bool pop_front(int* pElement = 0);         //删除第一个元素
	bool insert(int nIndex, int nElement);     //从任意位置添加
	bool erase(int nIndex, int* pElement = 0); //从任意位置删除
	bool remove(int nElement);                 //删除指定数据
	bool empty();                              //是否为空
	void clear();                              //清空所有
	int size();                                //获取当前元素个数
	bool setData(int nIndex, int nElement);    //修改下标为nIndex的元素的值为nData

	void Print();
private:

	LIST_NODE* m_pHeader;       //头指针
	int m_nCurrentCount;        //当前存储元素个数
};

//My_list.cpp

#include <stdio.h>
#include "My_list.h"


CMy_list::CMy_list():
m_pHeader(NULL), 
m_nCurrentCount(0)
{
}


CMy_list::~CMy_list()
{
}

//************************************
// Method:    push_back
// FullName:  CMy_list::push_back
// Access:    public 
// Returns:   bool
// Parameter: int nElement 新添加的元素
//************************************
bool CMy_list::push_back(int nElement)
{
	//判断是否为空表
	if (empty())
	{
		return push_front(nElement);
	}
	//找到最后一个元素
	LIST_NODE* pTemp = m_pHeader;
	// 1 2 3
// 	for (int i = 0; i < m_nCurrentCount-1;i++)
// 	{
// 		pTemp = pTemp->pNext;
// 	}
	while (pTemp->pNext)
	{
		pTemp = pTemp->pNext;
	}
	LIST_NODE* pNew = new LIST_NODE{};
	if (!pNew) return false;
	pNew->nData = nElement;
	//将原最后一个元素的pNext指向新的元素
	pTemp->pNext = pNew;
	m_nCurrentCount++;
	return true;
}

//************************************
// Method:    push_front
// FullName:  CMy_list::push_front
// Access:    public 
// Returns:   bool
// Parameter: int nElement  新添加的元素
//************************************
bool CMy_list::push_front(int nElement)
{
	//判断是否为空表
	if (empty())
	{
		m_pHeader = new LIST_NODE{};
		if (!m_pHeader) return false;
		m_pHeader->nData = nElement;
		m_nCurrentCount++;
		return true;
	}
	//如果不为空
	LIST_NODE* pNew = new LIST_NODE{};
	if (!pNew) return false;
	pNew->nData = nElement;
	pNew->pNext = m_pHeader;
	//m_pHeader指向新的元素(第一个)
	m_pHeader = pNew;
	m_nCurrentCount++;
	return true;
}

//************************************
// Method:    pop_back
// FullName:  CMy_list::pop_back
// Access:    public 
// Returns:   bool
// Parameter: pElement 存储被删除的数据
//************************************
bool CMy_list::pop_back(int* pElement/* = 0 */)
{
	//判断是否为空表
	if (empty())
	{
		return false;
	}
	//如果只有一个元素
	if (m_nCurrentCount == 1)
	{
		delete m_pHeader;
		m_pHeader = nullptr;
		m_nCurrentCount--;
		return true;
	}	
	//找到倒数第二个元素
	//1 2
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < m_nCurrentCount - 2;i++)
	{
		pTemp = pTemp->pNext;
	}
	//此时的pTemp就指向倒数第二个元素
	//直接删除即可
	delete pTemp->pNext;
	pTemp->pNext = NULL;
	m_nCurrentCount--;

	return true;
}

//************************************
// Method:    pop_front  删除第一个元素
// FullName:  CMy_list::pop_front
// Access:    public 
// Returns:   bool
// Parameter: pElement 存储被删除的数据
//************************************
bool CMy_list::pop_front(int* pElement/* = 0 */)
{
	//是否为空
	if (empty())
	{
		return false;
	}
	//如果只有一个元素
	if (m_nCurrentCount == 1)
	{
		delete m_pHeader;
		m_pHeader = nullptr;
		m_nCurrentCount--;
		return true;
	}
	//保存被删除的元素
	if (pElement)
	{
		*pElement = m_pHeader->nData;
	}
	//如果有多个元素,先保存第二个元素的地址
	LIST_NODE* pTemp = m_pHeader->pNext;
	//删除第一个元素
	delete m_pHeader;
	//m_pHeader指向原第二个元素的地址
	m_pHeader = pTemp;
	m_nCurrentCount--;
	return true;
}
//************************************
// Method:    insert
// FullName:  CMy_list::insert
// Access:    public 
// Returns:   bool
// Parameter: int nIndex   位置索引
// Parameter: int nElement    新添加的数据
//************************************
bool CMy_list::insert(int nIndex, int nElement)
{
	//1 [2] 3 4
	//索引是否有效
	if (nIndex < 0 || nIndex > m_nCurrentCount)
	{
		return false;
	}
	//判断是否为空表
	if (empty() /*|| nIndex == 0*/)
	{
		return push_front(nElement);
	}
	//找到插入位置的前一个元素
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < nIndex -1 ;i++)
	{
		pTemp = pTemp->pNext;
	}
	//1 [2] 3 4
	//此时的pTemp就是插入位置的前一个元素
	LIST_NODE* pNew = new LIST_NODE{};
	pNew->nData = nElement;
	//新的元素的pNext指向3
	pNew->pNext = pTemp->pNext;
	//指向新的元素
	pTemp->pNext = pNew;
	m_nCurrentCount++;
	return true;
}

//************************************
// Method:    erase
// FullName:  CMy_list::erase
// Access:    public 
// Returns:   bool
// Parameter: int nIndex   位置索引
// Parameter: int * pElement  被删除的数据(需要,就传一个有效地址)
//************************************
bool CMy_list::erase(int nIndex, int* pElement/* = 0*/)
{
	//索引是否有效
	if (nIndex < 0 || nIndex > m_nCurrentCount)
	{
		return false;
	}
	//判断是否为空表
	if (empty())
	{
		return false;
	}
	//如果是删除头部
	if (nIndex == 0)
	{
		return pop_front(pElement);
	}
	//找到删除位置的前一个元素
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < nIndex - 1; i++)
	{
		pTemp = pTemp->pNext;
	}
	//1 [2] 3 4
	//此时的pTemp就是删除位置的前一个元素(1)
	//保存被删除的元素
	if (pElement)
	{
		*pElement = pTemp->pNext->nData;
	}
	//保存3的地址
	LIST_NODE* p3 = pTemp->pNext->pNext;
	//删除2元素
	delete pTemp->pNext;
	//指向3
	pTemp->pNext = p3;
	m_nCurrentCount--;
	return true;
}

//************************************
// Method:    erase 删除元素
// FullName:  CMy_list::erase
// Access:    public 
// Returns:   bool
// Parameter: int nElement  要被删除的元素
//************************************
bool CMy_list::remove(int nElement)
{
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < m_nCurrentCount;i++)
	{
		if (nElement == pTemp->nData)
		{
			return erase(i);
		}
	}
	return false;
}

//************************************
// Method:    empty 是否是空表
// FullName:  CMy_list::empty
// Access:    public 
// Returns:   bool   
//************************************
bool CMy_list::empty()
{
	return m_nCurrentCount == 0;
}

//************************************
// Method:    clear  删除所有数据
// FullName:  CMy_list::clear
// Access:    public 
// Returns:   void
//************************************
void CMy_list::clear()
{
	//1 2 3
	LIST_NODE* pAfter = m_pHeader->pNext;
	LIST_NODE* pCurrent = m_pHeader;

	while (pAfter)
	{
		delete pCurrent;
		pCurrent = pAfter;
		pAfter = pAfter->pNext;
	}
	//删除最后一个元素
	delete pCurrent;
	m_pHeader = nullptr;
	m_nCurrentCount = 0;
}

//************************************
// Method:    size  获取当前元素个数
// FullName:  CMy_list::size
// Access:    public 
// Returns:   int    
//************************************
int CMy_list::size()
{
	return m_nCurrentCount;
}

//************************************
// Method:    setData  修改元素
// FullName:  CMy_list::setData
// Access:    public 
// Returns:   bool
// Parameter: int nIndex  位置索引
// Parameter: int nElement   修改之后的数据
//************************************
bool CMy_list::setData(int nIndex, int nElement)
{
	//判断索引是否有效
	if (nIndex < 0 || nIndex >= nElement)
	{
		return false;
	}
	//找到要修改的元素的位置
	//1 2 3
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < nIndex;i++)
	{
		pTemp = pTemp->pNext;
	}
	//此时的pTemp就是需要修改的元素
	pTemp->nData = nElement;
	return true;
}

void CMy_list::Print()
{
	LIST_NODE* pTemp = m_pHeader;
	for (int i = 0; i < m_nCurrentCount; i++)
	{
		printf("%d ", pTemp->nData);
		pTemp = pTemp->pNext;
	}
	printf("\n");
}


//main.cpp

#include <stdio.h>
#include "My_list.h"
int main()
{
	CMy_list lst;
	lst.push_back(1);
	lst.push_back(3);
	lst.push_back(4);
	lst.push_back(5);
	lst.push_back(6);
	lst.insert(1,2);
	lst.Print();

	int nData;
	lst.erase(0,&nData);
	lst.erase(2, &nData);
	lst.Print();
	lst.clear();
	return 0;
}