记录贴~~
说明:
- 用C++模板类写的,为了在其他文件中可以使用模板类的方法,所有实现都放在了头文件中(非常不以优雅…唉)
- 无头结点
singlelist.h
#ifndef __SINGLELIST__H
#define __SINGLELIST__H
#include <iostream>
using namespace std;
#define nullptr NULL
/* 节点结构,next指针和T类型数据 */
template<typename T>
class Node{
public:
T ele;
Node *next;
Node(){next=nullptr;}
};
/* 无头节点的单向链表 */
template<typename T>
class SingleList{
private:
Node<T> *m_nodeHead;//首节点
Node<T> *m_nodeTail;//尾结点
protected:
int cnt;
public:
SingleList(void)
{
m_nodeHead = nullptr;
m_nodeTail = nullptr;
cnt = 0;
cout << "["<< __FILE__ << "|" << __LINE__ << "]" << "constructor!" << endl;
}
~SingleList(void)
{
Node<T> *p = nullptr;
//遍历释放节点
while(nullptr != m_nodeHead)
{
p = m_nodeHead;
m_nodeHead = p->next;
delete p;
cout << "delete: " << p << endl;
p = nullptr;
m_nodeTail = nullptr;
}
cout << "["<< __FILE__ << "|" << __LINE__ << "]" << "deconstructor!" << endl;
}
//头插
int insertHead(const T& ele)
{
Node<T> *p = nullptr;
p = new Node<T>;
memcpy(&p->ele, &ele, sizeof(T));
//插入节点的next指向原来的首节点
p->next = m_nodeHead;
//旧的首节点为null,说明原来无节点,此时新的尾结点和新的首节点相同
if(nullptr == m_nodeHead)
{
m_nodeTail = p;
}
//新的首节点为插入的节点
m_nodeHead = p;
cnt ++;
return 0;
}
//获取首节点
int getHead(T& ele)
{
if(nullptr == m_nodeHead)
{
return -1;
}
memcpy(&ele, m_nodeHead, sizeof(T));
return 0;
}
//头删
int deleteHead(void)
{
Node<T> *p = nullptr;
p = m_nodeHead;
if(nullptr != p)
{
//新的首节点设为下一个节点
m_nodeHead = p->next;
//若新的首节点为null,说明无节点,尾结点也要设为null
if(nullptr == m_nodeHead)
{
m_nodeTail = nullptr;
}
//释放首节点
delete p;
cnt --;
}
return 0;
}
//尾插
int insertTail(const T& ele)
{
Node<T> *p = nullptr;
p = new Node<T>;
memcpy(&p->ele, &ele, sizeof(T));
//尾结点不为null,则在旧的尾结点后面继续加,并将新的结点改为新加的节点
if(nullptr != m_nodeTail)
{
m_nodeTail->next = p;
m_nodeTail = p;
}
//尾结点为null,说明无节点,新插入的节点成为新的首节点和新的尾结点
else
{
m_nodeTail = p;
m_nodeHead = p;
}
cnt ++;
}
//获取尾节点
int getTail(T& ele)
{
if(nullptr == m_nodeTail)
{
return -1;
}
memcpy(&ele, m_nodeTail, sizeof(T));
return 0;
}
//尾删
int deleteTail(void)
{
Node<T> *p = nullptr;
//旧的首节点和尾结点相同,且不为null,说明原链表只有一个节点
//则释放首节点,新的头节点和尾结点都为null
if(m_nodeHead == m_nodeTail && nullptr != m_nodeTail)
{
delete m_nodeTail;
m_nodeTail = nullptr;
m_nodeHead = nullptr;
cnt --;
}
//若原链表不止一个节点
else if(nullptr != m_nodeTail)
{
p = m_nodeHead;
//遍历,找到尾结点上一个节点,释放旧的尾结点,新的尾结点为旧的上一个节点
while(nullptr != p && m_nodeTail != p->next)
{
p = p->next;
}
p->next = nullptr;
delete m_nodeTail;
m_nodeTail = p;
cnt--;
}
return 0;
}
//链表长度
int getLen(void)
{
return cnt;
}
//清除
int clear(void)
{
Node<T> *p = nullptr;
//从头遍历,依次释放
while(nullptr != m_nodeHead)
{
p = m_nodeHead;
m_nodeHead = p->next;
delete p;
cout << "delete: " << p << endl;
p = nullptr;
}
m_nodeTail = nullptr;
cout << "clear!" << endl;
return 0;
}
//反转
void reverse(void)
{
Node<T> *p0 = nullptr;
Node<T> *p1 = nullptr;
Node<T> *p2 = nullptr;
if(m_nodeHead == m_nodeTail)
{
return;
}
p1 = m_nodeHead;
p2 = m_nodeHead->next;
m_nodeTail = p1;
m_nodeTail->next = nullptr;
while(p1 != nullptr && p2 != nullptr)
{
p0 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p0;
}
m_nodeHead = p1;
}
//遍历打印节点
void print(void (*func)(Node<T> *))
{
Node<T> *p = m_nodeHead;
cout << m_nodeHead << " " << m_nodeTail << endl;
while(nullptr != p)
{
cout << "<" << cnt << ">";
// cout << "<" << cnt << ">" << p << " " << p->ele << endl;
if(nullptr != func)
{
func(p);
}
p = (Node<T> *)(p->next);
}
cout << endl;
}
};
void SingleList_main01();
void SingleList_main02();
void SingleList_main03();
void SingleList_main04();
singlelist.cpp
/* 单链表练习
* 2022.04.01 20:14
*/
#include <iostream>
#include <string.h>
#include "singlelist.h"
using namespace std;
static void func(Node<int> *p)
{
cout << p << " " << p->ele << endl;
}
void SingleList_main01()
{
SingleList<int> sList;
sList.insertHead(101);
sList.print(func);
sList.insertHead(102);
sList.print(func);
sList.insertHead(103);
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.deleteHead();
sList.print(func);
}
void SingleList_main02()
{
SingleList<int> sList;
sList.insertTail(201);
sList.print(func);
sList.insertTail(202);
sList.print(func);
sList.insertTail(203);
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.insertHead(204);
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.deleteHead();
sList.print(func);
sList.insertHead(205);
sList.print(func);
sList.insertHead(206);
sList.print(func);
sList.insertHead(207);
sList.print(func);
}
void SingleList_main03()
{
SingleList<int> sList;
sList.insertTail(301);
sList.print(func);
sList.insertTail(302);
sList.print(func);
sList.insertTail(303);
sList.print(func);
sList.deleteTail();
sList.print(func);
sList.deleteTail();
sList.print(func);
sList.deleteTail();
sList.print(func);
sList.insertHead(304);
sList.print(func);
sList.insertHead(305);
sList.print(func);
sList.insertHead(306);
sList.print(func);
sList.clear();
sList.print(func);
}
void SingleList_main04()
{
SingleList<int> sList;
sList.insertTail(301);
sList.insertTail(302);
sList.insertTail(303);
sList.insertTail(304);
sList.insertTail(305);
sList.insertTail(306);
sList.print(func);
sList.reverse();
sList.print(func);
}