在使用有序链表作为基本数据结构时,当插入数据时,为了保持链表的有序性,我们需要两个指针来定位插入位置。通过递归我们可以巧妙的实现不要两个指针的做法。
// SortedSingleList.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/*
在单链表中有序插入元素时,一般使用两个指针,一个扫描指针,一个指向扫描指针前一项的指针,
因为单链表只能访问下一个元素,而无法访问上一个元素,所以当用扫描指针找到插入位置时,
需要通过前一项指针来访问插入位置
《编程珠玑》给出了一个通过递归的方法不使用两个指针的实现方法,代码如下
(通过实现一个集合的接口来体现,集合的底层实现是有序链表)
*/
#include<iostream>
using namespace std;
class MySet
{
private:
struct Node
{
int val;
Node* next;
Node(int val, Node* next = NULL) :val(val), next(next){}
};
Node* head;
Node* sentinel;
int elemCount;
int maxElem;
int n;
Node* rinsert(Node* p, int t)
{
if (p->val<t)
{
p->next = rinsert(p->next, t);
}
else if (p->val>t)
{
p = new Node(t, p);
n++;
}
return p;
}
public:
MySet(int elemCount, int maxElem) :elemCount(elemCount), maxElem(maxElem + 1), n(0)
{
head = sentinel = new Node(this->maxElem);
cout << "set para:" << "elemCount " << this->elemCount << " maxElem: " << this->maxElem << endl;
}
void insert(int x)
{
if (n == elemCount)
{
cerr << "set is full" << endl;
}
else
{
head = rinsert(head, x);
}
}
int size()
{
return n;
}
void report(int* res)
{
int j = 0;
for (Node* p = head; p != sentinel; p = p->next)
{
res[j++] = p->val;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = { 5, 7, 4, 8, 3, 2, 9, 6, 4, 8, 1 };
int n = sizeof(a) / sizeof(a[0]);
MySet mset(n, 9);
int *res = new int[n];
for (int i = 0; i<n; ++i)
{
res[i] = 0;
}
mset.report(res);
int nn = mset.size();
cout << "before insert" << endl;
for (int i = 0; i<nn; ++i)
{
cout << res[i] << " ";
}
cout << endl;
cout << "after insert" << endl;
for (int i = 0; i<n; ++i)
{
mset.insert(a[i]);
}
mset.report(res);
nn = mset.size();
for (int i = 0; i<nn; ++i)
{
cout << res[i] << " ";
}
cout << endl;
delete[] res;
return 0;
}