头文件CNode.h
#pragma once
template<class T>
class TLinkList;
template<class T>
class TOrderedLinkList;
class CNode
{
public:
friend class TLinkList<int>;
/*friend class TOrderedLinkList<int>;*/
CNode(int value);
~CNode();
int m_value;
CNode* m_pNext;
CNode* m_pPre;
};
CNode::CNode(int value)
{
m_value = value;
m_pNext = NULL;
m_pPre = NULL;
}
CNode::~CNode() {}
template<class T>
class TLinkList
{
public:
TLinkList();
~TLinkList();
virtual bool Insert(T value);//在链表中插入一个值,头插
bool Delete(T value);//删除结点值为value的结点
bool Search(T value);//判断链表中是否有值为value的结点
bool Modify(T v1, T v2);//查找结点为v1,修改为v2
virtual void Print();
CNode* m_pHead;
};
template<class T>
class TOrderedLinkList :public TLinkList<T>
{
public:
CNode* m_pHead;
TOrderedLinkList(); //构造函数
virtual ~TOrderedLinkList(); //析构函数
virtual bool Insert(T value); //有序插入
virtual void Print(); //按照链表顺序输出链表中的节点值
};
源文件
#include<iostream>
#include "CNode.h"
using namespace std;
//提前声明两个链表类 否则使用友元时会报错
template<class T>
TLinkList<T>::TLinkList()
{
m_pHead = NULL;
}
template<class T>
TLinkList<T>::~TLinkList()
{
CNode* p = m_pHead;
for (; p != NULL;)
{
m_pHead = p->m_pNext;//将头指针指向下一节点
delete p; //释放掉该p指针
p = m_pHead; //将新的结点设置为头指针
}
}
template<class T>
bool TLinkList<T>::Insert(T value)
{
CNode* pTemp = new CNode(value);//创建一个新的临时结点
if (pTemp == NULL)//申请内存不成功 退出程序
exit(0);
if (m_pHead == NULL)//头指针为空
{
pTemp->m_pNext = NULL;
pTemp->m_pPre = NULL;
m_pHead = pTemp;
}
else
{
pTemp->m_pNext = m_pHead; // 1. 将原头节点设置为新头节点的后继
pTemp->m_pPre = NULL; // 2. 将新头节点的前驱设置为NULL
m_pHead->m_pPre = pTemp; // 3. 将新头节点设置为原头节点的前驱
m_pHead = pTemp; // 4. 将新头节点设置为新的表头。
}
return true;
}
template<class T>
bool TLinkList<T>::Delete(T value)
{
bool flag = false;
CNode oCN(0);//0表示没有删除任何结点,1表示删除了
oCN.m_pNext = m_pHead;//在头指针前添加一个结点 方便结点的删除
oCN.m_pPre = NULL;
m_pHead->m_pPre = &oCN;
m_pHead = &oCN;
CNode* p1 = m_pHead, * p2 = m_pHead->m_pNext;
for (; p2 != NULL;)
{
if (p2->m_value == value)//p2所指的结点正是要删除的结点
{
p1->m_pNext = p2->m_pNext;
(p2->m_pNext)->m_pPre = p1;
delete p2;
p2 = p1->m_pNext;
flag = true;
}
else
{
p1 = p2;
p2 = p2->m_pNext;
}
}
m_pHead = oCN.m_pNext;
(oCN.m_pNext)->m_pPre = NULL;
return flag;
}
template<class T>
bool TLinkList<T>::Search(T value)
{
for (CNode* p = m_pHead; p != NULL; p++)
{
if (p->m_value == value)
{
return true;
}
}
return false;
}
template<class T>
bool TLinkList<T>::Modify(T v1, T v2)
{
bool flag = false;
for (CNode* p = m_pHead; p != NULL; p++)
{
if (p->m_value == v1)
{
p->m_value = v2;
flag = 1;
}
}
return flag;
}
template<class T>
void TLinkList<T>::Print()
{
cout << "从TLinkList表头开始结点的值依次为:\n";
for (CNode* p = m_pHead; p != NULL; p = p->m_pNext)
{
cout << p->m_value << " ";
}
cout << endl;
}
template <class T>
TOrderedLinkList<T>::TOrderedLinkList()
{
m_pHead = NULL;
}
//TOrderedLinkList类模板的构造函数
template <class T>
TOrderedLinkList<T>::~TOrderedLinkList()
{ }
template <class T>
bool TOrderedLinkList<T>::Insert(T value)
{
CNode* p1,
* p2; //定义两个指针插入操作时使用
CNode* pTemp = new CNode(value);//定义pTemp指向new的待插入节点
if (pTemp == NULL) //内存空间申请不成功
{exit(0);} //停止执行程序
if (m_pHead == NULL) //表头为空时插入为第一个节点
{
pTemp->m_pNext = NULL; //1. 新节点的后继为NULL
pTemp->m_pPre = NULL; //2. 新节点的前驱为NULL
m_pHead = pTemp; //3. 头指针指向新节点
}
else //当表头不为空时,首先要寻找插入位置,然后才能插入节点
{
if (value < m_pHead->m_value) //在表的头节点前插入
{
pTemp->m_pNext = m_pHead; // 1. 将原头节点设置为新头节点的后继
pTemp->m_pPre = NULL; // 2. 将新头节点的前驱设置为NULL
m_pHead->m_pPre = pTemp; // 3. 将新头节点设置为原头节点的前驱
m_pHead = pTemp; // 4. 将新头节点设置为新的表头。
}
else //不是在头节点前插入
{ //让p2指向p1的前驱(主要考虑链表尾部的插入)
for (p2 = m_pHead, p1 = m_pHead->m_pNext; p1 != NULL; p2 = p1, p1 = p1->m_pNext)
{
if (value < p1->m_value) // 在链表中间插入
{
(p1->m_pPre)->m_pNext = pTemp; // 1. p1的前驱的后继指向新节点
pTemp->m_pPre = p1->m_pPre; // 2. 新节点的前驱指向p1的前驱
pTemp->m_pNext = p1; // 3. 新节点的后继指向p1
p1->m_pPre = pTemp; // 4. p1的前驱指向新节点
break;
}
}
if (p1 == NULL) // 在链表末尾插入
{
pTemp->m_pNext = NULL; // 1. 新节点的后继设置为NULL
pTemp->m_pPre = p2; // 2. 新节点的前驱指向p2
p2->m_pNext = pTemp; // 3. p2的后继指向新节点
}
}
}
return true;
}
template<class T>
void TOrderedLinkList<T>::Print()
{
for (CNode* p = m_pHead; p != NULL; p = p->m_pNext)
{
cout << p->m_value << " ";
}
cout << endl;
}
int main()
{
TLinkList<int> oILL;
oILL.Insert(12);
oILL.Insert(24);
oILL.Insert(48);
oILL.Insert(96);
oILL.Insert(24);
oILL.Insert(48);
oILL.Insert(96);
oILL.Insert(35);
oILL.Print();
oILL.Delete(24);
oILL.Print();
return 0;
}