建立一个(极简版的)链表类(单向链表)。
用指针实现链表的有序添加数据,使链表内的数据满足从小到大排序。
可以在此基础上扩展出许多功能,稍稍改动就可以用来解决“1000个数找出前5个最小数”等类似问题。
扩展为“图”结构,见下一节。
实现代码:
//chain.h
//链表节点
struct node
{
int data;
node * next;
node(int a):data(a),next(NULL){}
};
//链表
class chain
{
public:
int lengthChain;
node * nodeHead;
chain():lengthChain(0),nodeHead(NULL){}
chain(const chain &c)//复制构造函数
{
lengthChain = c.lengthChain;
if (c.nodeHead != NULL)
{
node * pHc = c.nodeHead;
nodeHead = new node(pHc->data);
pHc = pHc->next;
node * pH = nodeHead;
while (pHc != NULL)
{
pH->next = new node(pHc->data);
pH = pH->next;
pHc = pHc->next;
}
}
else
nodeHead = NULL;
}
~chain()
{
if (nodeHead != NULL)
{
node * pH = nodeHead;
nodeHead = NULL;
while (pH != NULL)
{
node * pDel = pH;
pH = pH->next;
delete pDel;
}
}
}
void addNode(int a);
int delNode(int index);//删除索引为 index 的数据
void showNode();
};
//chain.cpp
#include <iostream>
#include "chain.h"
//添加数据
void chain::addNode(int a)
{
node * p = new node(a);
if (nodeHead == NULL || nodeHead->data >= a)//从小到大排序
{
p->next = nodeHead;
nodeHead = p;
}
else
{
node * pH = nodeHead;
while (pH->next != NULL && pH->next->data < a)//从小到大排序
pH = pH->next;
p->next = pH->next;
pH->next = p;
}
lengthChain++;
return;
}
//删除索引为 index 的数据
int chain::delNode(int index)
{
if (lengthChain <= 0 || index >= lengthChain || index < 0)
return -1;
int res;//返回值,删除的数据
if (index == 0)
{
node * pDel = nodeHead;
nodeHead = nodeHead->next;
res = pDel->data;
delete pDel;
}
else
{
node * pH = nodeHead;
while (index > 1)//这里需要 >1,因为要得到前面的那个节点的指针
{
pH = pH->next;
index--;
}
node * pDel = pH->next;
pH->next = pH->next->next;
res = pDel->data;
delete pDel;
}
lengthChain--;
return res;
}
//显示链表
void chain::showNode()
{
using namespace std;
if (nodeHead != NULL)
{
node * pH = nodeHead;
while (pH != NULL)
{
cout << " " << pH->data;
pH = pH->next;
}
cout << endl;
cout << "lengthChain == " << lengthChain << endl;
}
else
cout << "This chain is empty!" << endl;
return;
}
//2_4_node_fn
//单向链表
#include <iostream>
#include "chain.h"
int main()
{
using namespace std;
chain c;
int n,a;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a;
c.addNode(a);//给链表添加数据
}
c.showNode();//显示链表
chain ac = c;//调用复制构造函数
int index;
cin >> index;
ac.delNode(index);//删除链表中索引为 index 的数据
ac.showNode();//显示链表
return 0;
}
稍稍改动就可以用来解决“1000个数找出前5个最小数”等类似问题,如重载函数void addNode(int a, int fn);其中fn表示存储前fn个最小的数据。添加数据时,只保留前 fn 个最小的数据。
void chain::addNode(int a, int fn)//添加 fn //存储前 fn 个最小的数据
{
if (fn <= 0)//添加 fn
return;
if (nodeHead == NULL || nodeHead->data >= a)//从小到大排序
{
node * p = new node(a);
p->next = nodeHead;
nodeHead = p;
}
else
{
fn--;//添加 fn
if (fn <= 0)//添加 fn
return;
node * pH = nodeHead;
while (pH->next != NULL && pH->next->data < a)//从小到大排序
{
pH = pH->next;
fn--;//添加 fn
if (fn <= 0)//添加 fn
return;
}
node * p = new node(a);
p->next = pH->next;
pH->next = p;
}
return;
}