单向链表的应用举例

1.单向链表的倒置

思路:取原链表的每一个结点,将其作为第一个结点插入到新链表中。

template<class Type>
void LinkedList <Type> :: Inverse ()
{
	ListNode<Type> *p, *head = new ListNode<Type> ();
	while (first != NULL) 
    {
		p = first;  
        first = first->link;		//摘下first链头结点  
		p->link = head->link;  
		head->link = p;	//插入head链前端
	}
	first = head->link; 
	delete head;			//重置first
}


2.实现一个Locate运算的函数,使频繁访问的结点总是靠近表头。

思路:利用双向链表的特点,若找到,修改访问频度域,顺左链查找适当的位置插入。

#include <iostream>

//双向循环链表结点的构造函数
DoubleNode(Type value, DoubleNode<Type> * lLink, DoubleNode<Type> *rLink) :
	data(value), freq(0), left(lLink), right(rLink) {}
DoubleNode(Type value) :
	data(value), freq(0), left(NULL), right(NULL) {}

template <class Type>
DoubleList<Type> :: DoubleList (Type uniqueVal)
{
	first = new DoubleNode<Type>(uniqueVal);
	first->right= first->left = first;		//创建表头结点
	current = NULL;
	cout << "开始建立双向循环链表:\n";
	Type value;
	cin >> value;
	while (value != uniqueVal)
    {		//每次新结点插入在表头结点后面
   		first->right = new DoubleNode<Type>(value, first, first->right);
   		cin >> value;
	}
}

template <class Type>
void DoubleList<Type> :: Locate (Type & x)
{
	DoubleNode<Type> *p = first->right;
	while (p != first && p->data != x) p = p->right;
	if (p != first)      //链表中存在x
    {
	  	p->freq++;						//该结点的访问频度加1
		current = p;						//从链表中摘下这个结点
		current->left->right = current->right;
		current->right->left = current->left;
		p = current->left;					//寻找从新插入的位置
		while (p != first && current->freq > p->freq)
			p = p->left;
		current->right = p->right;			//插入在p之后
		current->left = p;
		p->right->left = current;
		p->right = current;
	}
	else cout << "Sorry. Not find!\n";		//没找到
}
//假设表中元素个数为n,则该算法的时间复杂度为O(n)

3.union-find问题(并查集)

在线等价类问题

void Initialize(int n)  //初始化n个类, 每个类仅有一个元素
{
    node = new EquivNode[n + 1];
    for (int e = 1; e <= n; e++)
    {
        node[e].E = e;
        node[e].link = 0;
        node[e].size = 1;
    }
}

void Union(int i, int j)  //合并类i和类j, 使i代表较小的类
{
    if (node[i].size > node[j].size)
        swap (i, j);
    //改变较小类的E值
    int k;
    for (k = i; node[k].link; k = node[k].link)
        node[k].E = j;
    node[k].E = j; //链尾结点
    //在链表j的首结点之后插入链表i, 并修改新链表的大小
    node[j].size += node[i].size;
    node[k].link = node[j].link;
    node[j].link = i;
}

int Find(int e)
{   //搜索包含元素i的类
    return node[e].E;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值