递归实现有序链表(不需要使用两个指针)

在使用有序链表作为基本数据结构时,当插入数据时,为了保持链表的有序性,我们需要两个指针来定位插入位置。通过递归我们可以巧妙的实现不要两个指针的做法。

// 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;
}

点赞