list的模拟及其实现

 list容器概述:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通 过链表中的指针链接次序实现的。list是一个双向循环链表

                   

具体和这个图差不多

 

 



文章目录

  • 一.list的基本API
  • 二.list的使用
  • 三.list的模拟实现


一、list的基本API

3.6.4.1 list 构造函数
list<T> lstT;//list 采用采用模板类实现,对象的默认构造形式:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将 n 个 elem 拷贝给本身。
list(const list &lst);//拷贝构造函数。
3.6.4.2 list 数据元素插入和删除操作
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在 pos 位置插 elem 元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在 pos 位置插入 n 个 elem 数据,无返回值。
insert(pos,beg,end);//在 pos 位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除 pos 位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与 elem 值匹配的元素。
3.6.4.3 list 大小操作
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(num);//重新指定容器的长度为 num,
若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem);//重新指定容器的长度为 num,
若容器变长,则以 elem 值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
3.6.4.4 list 赋值操作
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将 n 个 elem 拷贝赋值给本身。
list& operator=(const list &lst);//重载等号操作符
swap(lst);//将 lst 与本身的元素互换。
3.6.4.5 list 数据的存取
front();//返回第一个元素。
back();//返回最后一个元素。
3.6.4.6 list 反转排序
reverse();//反转链表,比如 lst 包含 1,3,5 元素,运行此方法后,lst 就包含 5,3,1
元素。
sort(); //list 排序
3.6.4.6 list 反转排序
reverse();//反转链表,比如 lst 包含 1,3,5 元素,运行此方法后,lst 就包含 5,3,1
元素。
sort(); //list 排序

二、常见API的使用

#include<iostream>
#include<list>
using namespace std;

int main()
{

    list<int> lt;
    lt.push_back(10);
    lt.push_back(20);
    lt.push_back(30); 
    lt.push_back(40);
    lt.push_back(50);
    lt.push_back(10);

    list<int>::iterator it = lt.begin();
    while (it != lt.end())
    {
        cout << *it;
        ++it;
        cout << endl;
    }
    cout << endl;

    system("pause");
    return 0;
}


 

三.list的模拟及其实现

#pragma once
#include<assert.h>
namespace zdc
{

	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _next;//节点后指针
		list_node<T>* _prev;//指向前面的指针
		list_node(const T& x = T())
			:_data(x)
			, _next(nullptr)
			, _prev(nullptr)
		{}
	};
	template<class T, class Ref, class Ptr>//用于控制迭代器对象是看不是constduixiang

	struct __list_iterator//实现迭代器
	{
		typedef list_node<T> Node;//结构体指针
		typedef __list_iterator<T, Ref, Ptr> iterator;//普通迭代器T引用

		//typedef bidirectional_iterator_tag iterator_category;
		//typedef T value_type;
		//typedef Ptr pointer;
		//typedef Ref reference;
		//typedef ptrdiff_t difference_type;
		//

		Node* _node;//
		__list_iterator(Node*node)//用这个指针来构造
			:_node(node)
		{}
		bool operator !=(const iterator& it)const
		{
			return _node != it._node;//不等于比大小可以用指针来比

		}
		bool operator==(const iterator& it) const
		{
			return _node == it._node;
		}
		//*it就是返回it里的数据可以都或者xie
		Ref operator*()
		{
			return _node->_data;//引用返回可以修改
		}
		Ptr operator->()//用模板参数控制迭代器类型
		{
			return &(operator*());//这个实际胜率了一个-》Node*->it->
		}
		iterator& operator++()
		{
			_node = _node->_next;//所谓++就是指向下一个位置it=——node
			return *this;
		}
		iterator& operator++(int)
		{
			iterator tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		iterator& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		iterator operator--(int)
		{
			iterator tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

	};

	template<class T>
	class list
	{
		typedef list_node<T> Node;//结构体指针

	public:
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;




		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}
		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

		const_iterator end() const
		{
			return const_iterator(_head);
		}

			list()
		    {
		//		_head = new Node;//开辟新节点不需要存储数据
		//		_head->_next = _head;
		//		_head->_prev = _head;//形成循环链表
				empty_init();
			}
			void empty_init()
			{
				_head = new Node;//开辟新节点不需要存储数据
				_head->_next = _head;
				_head->_prev = _head;//形成循环链表
				//创建并初始化头结点

			}
			template <class InputIterator>
			list(InputIterator first, InputIterator last)
			{
				empty_init();//先初始化

				while (first != last)//相当与begin !=end
				{
					push_back(*first);//取数据逐渐尾插
					++first;//其实就是便利数据然后尾插
				}
			}
			list<T>& operator=(list<T> it)//赋值
			{
				swap(it);
				return *this;
			}
			void swap(list<T> &tmp)
			{
				std::swap(_head, tmp._head);
			}
			list(const list<T> &it)//拷贝构造

			{
				empty_init();//先把自己初始化
				list<T>tmp(it.begin(), it.end());
				swap(tmp);
			}
			~list()
			{
				clear();
				delete _head;//删除头结点 
				_head = nullptr;
			}
		void push_back(const T& x)
		{
			//Node*tail = _head->_prev;//因为循环链表的原因他的尾
			//Node* newnode = new Node(x);//这里调用了默认构造函数

			//链接过程 __ _head   tail   newnode

			//tail->_next = newnode;//
			//newnode->_prev = tail;
			//newnode->_next = _head;//这个东西看图很清晰的
			//_head->_prev = newnode;

			//写好insert可以直接复用
			insert(end(), x);//找到尾部,无非就是end这个位置
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);//返回下一位置迭代器
			}
		}
		void push_front(const T& x)//头插也可以复用insert
		{
			insert(begin(), x);
		}
		
		iterator erase(iterator pos)
		{
			assert(pos != end());//判断是不是头结点,头结点不能删除
			Node*cur = pos._node;//cur存储迭代器指针
			Node*prev = cur->_prev;
			Node*next = cur->_next;//找到要删除节点的下一个

			//接下来就是三个节点的关系处理了 prev  cur next
			prev->_next = next;
			next->_prev = prev;
			delete cur;//释放节点

			return iterator(next);/*返回新节点的next*/
		}
		iterator insert(iterator pos, const T& x)//插入
		{
			Node*cur = pos._node;//pos是节点的指针
			Node*prev = cur->_prev;//迭代器的前一个位置
			Node* newnode = new Node(x);

			//prev  newnode  cur的链接方式
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);//返回迭代器位置的指针

		}
	/*	void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}*/
		void pop_back()
		{
			erase(--end());//头删
		}
		void pop_front()
		{
			erase(begin());
		}


	private:
		Node* _head;//头结点



	};






}

                                    这里举例几个重要的接口   

                                                   

//插入的接口

iterator insert(iterator pos, const T& x)//插入
		{
			Node*cur = pos._node;//pos是节点的指针
			Node*prev = cur->_prev;//迭代器的前一个位置
			Node* newnode = new Node(x);

			//prev  newnode  cur的链接方式
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);//返回迭代器位置的指针

		}

                                    

                 //ps:自己画的草图比较丑请见谅结合注释的                                         push_back来看这个图比较好

                         当然这个也要注意深浅拷贝问题 

                                                这里深浅拷贝参考了stl源码的设计

	template <class InputIterator>
			list(InputIterator first, InputIterator last)
			{
				empty_init();//先初始化

				while (first != last)//相当与begin !=end
				{
					push_back(*first);//取数据逐渐尾插
					++first;//其实就是便利数据然后尾插
				}
			}

             void empty_init()
			{
				_head = new Node;//开辟新节点不需要存储数据
				_head->_next = _head;
				_head->_prev = _head;//形成循环链表
				//创建并初始化头结点

			}

            	}
			list(const list<T> &it)//拷贝构造

			{
				empty_init();//先把自己初始化
				list<T>tmp(it.begin(), it.end());
				swap(tmp);
			}


            //第二个函数是为了初始化头结点
             //第一个函数是为了让迭代器初始化空间
               //第三个拷贝构造用的是现代写法

RIP (Routing Information Protocol) 是一种基于距离向量算法的动态路由协议,用于在局域网(LAN)或广域网(WAN)上交换路由信息。下面是一个简单的 Java 实现 RIP 协议的模拟代码: ```java import java.util.*; public class RIPSimulator { private static final int MAX_COST = 16; private static final int INFINITY = 9999; private static class Route { int dest; int cost; int nextHop; public Route(int dest, int cost, int nextHop) { this.dest = dest; this.cost = cost; this.nextHop = nextHop; } } private static class Router { int id; List<Route> routingTable; Map<Integer, Integer> neighbors; public Router(int id) { this.id = id; routingTable = new ArrayList<>(); neighbors = new HashMap<>(); } public void addNeighbor(int neighborId, int cost) { neighbors.put(neighborId, cost); routingTable.add(new Route(neighborId, cost, neighborId)); } public void updateRoutingTable(List<Route> routes) { boolean changed = false; for (Route route : routes) { if (route.cost >= INFINITY) { continue; } int newCost = route.cost + neighbors.get(route.nextHop); Optional<Route> existingRoute = routingTable.stream() .filter(r -> r.dest == route.dest) .findFirst(); if (existingRoute.isPresent()) { if (newCost < existingRoute.get().cost) { existingRoute.get().cost = newCost; existingRoute.get().nextHop = route.nextHop; changed = true; } } else { routingTable.add(new Route(route.dest, newCost, route.nextHop)); changed = true; } } if (changed) { System.out.println("Router " + id + " updated routing table:"); printRoutingTable(); } } public void printRoutingTable() { System.out.println("Destination\tCost\tNext Hop"); routingTable.forEach(route -> { System.out.println(route.dest + "\t\t" + route.cost + "\t\t" + route.nextHop); }); } } public static void main(String[] args) { List<Router> routers = new ArrayList<>(); // Add routers and their neighbors Router r1 = new Router(1); r1.addNeighbor(2, 1); r1.addNeighbor(3, 3); r1.addNeighbor(4, 7); routers.add(r1); Router r2 = new Router(2); r2.addNeighbor(1, 1); r2.addNeighbor(3, 1); r2.addNeighbor(4, 2); routers.add(r2); Router r3 = new Router(3); r3.addNeighbor(1, 3); r3.addNeighbor(2, 1); r3.addNeighbor(4, 2); routers.add(r3); Router r4 = new Router(4); r4.addNeighbor(1, 7); r4.addNeighbor(2, 2); r4.addNeighbor(3, 2); routers.add(r4); // Simulate RIP updates for (int i = 0; i < 10; i++) { for (Router router : routers) { List<Route> routes = new ArrayList<>(); for (Router neighbor : routers) { if (router.neighbors.containsKey(neighbor.id)) { routes.addAll(neighbor.routingTable); } } router.updateRoutingTable(routes); } } } } ``` 此代码模拟了一个由 4 个路由器组成的网络,每个路由器都有若干个邻居路由器,每个路由器的初始路由表包含它的邻居路由器及其距离。在模拟过程中,每个路由器都向其邻居路由器请求路由表,并根据收到的路由表更新自己的路由表,直到收敛为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨白1357

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值