有序链表操作
掌握有序链表的基本操作:插入、删除、查找。
掌握链表遍历器的使用方法。
#pragma once
#include <iostream>
using namespace std;
class OutOfBounds {
public:
OutOfBounds() {
cout << "Wrong" << endl;
}
};
class Title {
public:
Title() {
cout << "Title error" << endl;
}
};
int newProgram(size_t size) {
throw Title();
}
template <class T>
class fjxChainNode {
public:
T data;
fjxChainNode<T>* node;
};
template <class T>
class myChain {
public:
myChain() { head = 0; }//构造函数
~myChain();//析构函数,就是删掉链表中的每一个节点
bool IsEmpty()const {//判断链表是不是没有元素
return head == 0;
}
int myLength()const;//返回链表的长度
void fjxErase();//删除链表中的所有节点
void fjxOutput(ostream& out) const;//输出链表
int fjxSearch(const T& x)const;//寻找是否存在x这个值
myChain<T>& fjxInsert(int k, const T& x);//插入节点
myChain<T>& fjxAutoNew(const T& x);//自动寻找位置并插入节点
myChain<T>& fjxAppend(const T& x);//在链表的最后加上元素
myChain<T>& fjxMerge(myChain<T>& A, myChain<T>& B);//求两个链表的和
fjxChainNode<T>* last;
fjxChainNode<T>* head;
};
//析构函数
template <class T>
myChain<T>::~myChain<T>() {
fjxErase();
}
//返回链表的长度
template <class T>
int myChain<T>::myLength()const {
fjxChainNode<T>* p = head;
int length = 0;
while (p != NULL) {
length++;
p = p->node;//每往下移动一个节点,len就加1;
}
return length;
}
//第几个元素是x元素
template <class T>
int myChain<T>::fjxSearch(const T& x)const {
fjxChainNode<T>* p = head;
int index = 1;
while (p != NULL && p->data != x) {//如果存在p节点,并且没有当前元素的值不为x,就往下移动,寻找下一个节点
p = p->node;
index++;
}
if (p != NULL) {//如果当前节点存在的话,返回index,表示元素在第index个,如果index为0,说明没有找到
return index;
}
return 0;
}
//输出链表
template<class T>
void myChain<T>::fjxOutput(ostream& out)const {
fjxChainNode<T>* p;
for (p = head; p != NULL; p = p->node) {
out << p->data;
if (!p->node) {
out << endl;
}
else {
out << ",";
}
}
}
//重载操作符
template<class T>
std::ostream& operator<<(std::ostream& out, const myChain<T>& x) {
x.fjxOutput(out);
return out;
}
//插入操作
template <class T>
myChain<T>& myChain<T>::fjxInsert(int k, const T& x) {
if (k < 0)throw OutOfBounds();
fjxChainNode<T>* p = head;
for (int index = 1; index < k && p != NULL; index++) {
p = p->node;//移动到第k个节点
}
if (k > 0 && p == NULL) {
throw OutOfBounds();
}
fjxChainNode<T>* t = new fjxChainNode<T>();
t->data = x;
if (k) {
t->node = p->node;
p->node = t;
}
else {
t->node = head;
head = t;
}
return *this;
}
//自动插入操作
template <class T>
myChain<T>& myChain<T>::fjxAutoNew(const T& x) {
fjxChainNode<T>* p = head;
//创建新增节点
fjxChainNode<T>* t = new fjxChainNode<T>();
t->data = x;
//空链表时
if (p == 0) {
head = t;
return *this;
}
else {
if (x <= head->data) {
t->node = p;
head = t;
return *this;
}
//中间
while (p->node) {
if (p->data <= x && x <= p->node->data) {
t->node = p->node;
p->node = t;
break;
}
p = p->node;
}
//尾部
p->node = t;
}
return *this;
}
template <class T>
void myChain<T>::fjxErase() {
fjxChainNode<T>* next;
while (head) {
next = head->node;
delete head;
head = next;
}
}
template <class T>
myChain<T>& myChain<T>::fjxAppend(const T& x) {
fjxChainNode<T>* t = new fjxChainNode<T>();
t->data = x;
t->node = 0;//空指针还有野指针必须附上零或者空
if (head) {
last->node = t;//代表使last的下一个节点是t
last = t;
}
else {
head = last = t;
}
return *this;
}
template <class T>
myChain<T>& myChain<T>::fjxMerge(myChain<T>& A, myChain<T>& B)
{
fjxChainNode<T>* pa = A.head;
fjxChainNode<T>* pb = B.head;
fjxChainNode<T>* pc = 0;
fjxChainNode<T>* head = 0;
fjxChainNode<T>* q = 0;
while (pa != NULL && pb != NULL) {
if (pa->data <= pb->data) {
q = pa;
pa = pa->node;
}
else {
q = pb;
pb = pb->node;
}
if (pc == 0) { head = q; pc = q; }
else { pc->node = q; pc = q; }
}
if (pa != NULL) pc->node = pa;
else pc->node = pb;
A.head = 0;
B.head = 0;
return *this;
}
//遍历器
template <class T>
class ChainIterator {
public:
T* Initialize(const myChain<T>& c) {
location = c.head;
if (location) {
return &location->data;
}
return 0;
}
T* Next() {
if (!location)
return 0;
location = location->node;
if (location)
return &location->data;
return 0;
}
private:
fjxChainNode<T>* location;
};
//创建一个新的有序线性表C,该表中包含了A和B的所有元素。
template <class T>
void Merge(const myChain<T>& A, const myChain<T>& B, myChain<T>& C) {
ChainIterator<T> a, b;//链表A,B的遍历器
T* DataA = a.Initialize(A);//指向A中元素的指针
T* DataB = b.Initialize(B);//指向B中元素的指针
C.fjxErase();
while (DataA && DataB)
{
if (*DataA <= *DataB)
{
C.fjxAppend(*DataA);
DataA = a.Next();
}
else
{
C.fjxAppend(*DataB);
DataB = b.Next();
}
}
if (DataA)
while (DataA)
{
C.fjxAppend(*DataA);
DataA = a.Next();
}
else
while (DataB)
{
C.fjxAppend(*DataB);
DataB = b.Next();
}
}
int main() {
myChain<int>a;
myChain<int>b;
myChain<int>c;
cout << "Input1" << endl;
int num = -1;
while (num != 0) {
cin >> num;
if (num != 0)
a.fjxAutoNew(num);
}
cout << "Output1" << endl;
cout << a;
cout << "Input2" << endl;
cin >> num;
a.fjxAutoNew(num);
cout << "Output2" << endl;
cout << a;
cout << "Input3" << endl;
cin >> num;
cout << "Output3" << endl;
cout << a.fjxSearch(num) << endl;
cout << "Input4" << endl;
cin >> num;
cout << "Output4" << endl;
cout << a.fjxSearch(num) << endl;
cout << "Input5" << endl;
num = -1;
while (num != 0) {
cin >> num;
if (num != 0)
b.fjxAutoNew(num);
}
cout << "Output5" << endl;
cout << b;
Merge(a, b, c);
cout << c;
cout << "End" << endl;
return 0;
}