自主链表 之 前移法

1. 自主链表简介

在这里插入图片描述
在这里插入图片描述
下面给出其组织数据的方式:以一段数据流 A C B C D A D A C A C C E E

在这里插入图片描述

在前三中方法中,新信息存储到链表末尾新增的节点中;在第四种方法中,储存信息的新节点放在链表的某个位置,以保持链表的顺序。

2. 关于前移法的算法

/**
 * 
 * 
 * 前移法(Move-to-front method)。在找到需要的元素之后,把它放到链表的开头。
 * 
 * 
 * 
*/

#include<iostream>
using namespace std;

// 创建节点类
template<class T>
class Node {
public:
	Node() {
		next = 0;
	}
	Node(T e, Node* p = 0) 
    {
        this->data = e;
        this->next = p;
    }
	T data;			        
	Node<T>* next;	        
};

//创建一个单链表
template<class T>
class FrontList {
private:
	Node<T>* head;
public:
	FrontList();
	virtual ~FrontList();
	bool isEmpty() {	     
		return 0 == head;
	}
	void addToHead(T);          // 只以添加 头节点 的为例
	void deleteNode(T);        //   删除任意一节点
	void visit(T);             //  查找任意一个节点
    void print();              //   打印节点中的data	         
};

template<class T>
FrontList<T>::FrontList() {
	head = 0;
}

template<class T>
FrontList<T>::~FrontList(){
	for (Node<T>* p = 0; !isEmpty();) {
		p = head->next;
		delete head;
		head = p;
	}
}

template<class T>
void FrontList<T>::print() {
    Node<T>* p = head;
    while (p != NULL) {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}


template<class T>
void FrontList<T>::addToHead(T d) {
	head = new Node<T>(d, head);
}

template<class T>
void FrontList<T>::deleteNode(T d) {
	if (head == 0)
    {                 
        return;
	} 
    else if (head->data == d) 
    {
        Node<T>* tmp = head;
        head = head->next;
        delete tmp;
        return;
    }
    else
    {
        Node<T>* p = head;
        for(;p->next != NULL && p->next->data != d;p = p->next);
            
        if (p->next != NULL) 
        {
            Node<T>* tmp = p->next;
            p->next = tmp->next;
            delete tmp;
        }
    }
}

template<class T>
void FrontList<T>::visit(T d) 
{
	if (head == 0) 
    {                 
        return;
	} 
    else if (head->data == d) 
    {
        cout << "visit " << d << endl;
        return;
    }

	Node<T>* p = head;
    for(;p->next != NULL && p->next->data != d;p = p->next);
    if (p->next != NULL) 
    {
        Node<T>* tmp = p->next;
        p->next = tmp->next;
        Node<T>* tmp_head = head;
        head = tmp;
        head->next = tmp_head;
    }
    else
    {
        cout<<"No Founding  "<<d<<"  this element"<<endl;      //查询元素时 不存在
    }
    
}

int main() {
    FrontList<int> list;
    list.addToHead(1);
    list.addToHead(2);
    list.addToHead(3);
    list.print();
    list.visit(1);
    list.print();
    list.visit(50);
    system("pause");
    return 0;
}

    用前3种方法最有可能在链表表头附近找到元素,使用前移法最明确,而使用换位法要特别谨慎。
    对于这些方法效率的分析通常是将其效率与最佳静态排序*(optimal static ordering)*的效率进行比较。在最佳静态排序种,所有数据都根据在数据种出现的频率排序,因此,这种链表仅仅适用于查找,而不能用来插入新项。因此该方法需要扫描数据两次,一次建立链表,另一次是用链表进行查找。

总结:由此可以看出,对于中等大小的表,使用链表就足够了。随着数据量的增长和访问频率的提高,需要使用更复杂的方法和数据结构
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值