顺序表和链表

一、复习STL

STL(标准数据库):不仅是一个可复用的组件库,而且是一个包罗算法和数据结构的软件框架。

(1)容器:各种数据结构(string、vector、list、map、set、multimap、multilset)

(2)迭代器:扮演容器和算法的胶合剂(iterator)

(3)空间配置器:负责内存空间的分配与管理(allocator)解决内存碎片

(4)配接器(适配器):一种修饰容器或者仿函数或者迭代器接口的东西(stack、queue)

(5)算法:各种算法(sort、search、copy等)

(6)仿函数:行为类似函数的类,用作算法的,某种策略

六者之间的关系:


二、顺序表和链表的区别

为什么有顺序表又有链表?

答:因为顺序表和链表各有优点,谁也无法取代谁

1、顺序表

优点:存取速度高效,通过下标来直接存储

缺点:插入和删除比较慢

          不可以增长长度

2、链表

优点:插入和删除比较快,保留原有的物理顺序

缺点:查找速度慢,因为查找时,要循环的访问链表

三、实现代码

1、Vector.h

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
//顺序表
typedef int DataType;
class Vector
{
public:
	Vector()//构造函数
		:_first(NULL)
		,_finish(NULL)
		,_endofstorage(NULL)
	{}
	Vector(Vector& v)//拷贝构造
	{
		if (v.Size () > 0)
		{
			_first = new DataType[v.Size()];
			memcpy(_first, v._first, sizeof(DataType)*v.Size());

			_finish = _first + v.Size();
			_endofstorage = _first + v.Size();
		}
		else
		{
			_first = _finish = _endofstorage = NULL;
		}
	}
	Vector& operator=(Vector v)//赋值运算符
	{
		swap(_first, v._first);
		swap(_finish, v._finish);
		swap(_endofstorage, v._endofstorage);

		return *this;
	}
	~Vector()//析构函数
	{
		delete[] _first;
		_first = _finish = _endofstorage = NULL;
	}

	size_t Size()//求顺序表的长度
	{
		return _finish - _first;
	}
	size_t Capacity()//求容
	{
		return _endofstorage - _first;
	}
	void Expand(size_t n)//扩容
	{
		if (n > Capacity())
		{
			size_t size = Size();
			DataType* tmp = new DataType[n];

			if (_first)
			{
				memcpy(tmp, _first, sizeof(DataType)*Size());
				delete[] _first;
			}
			_first = tmp;
			_finish = _first + size;
			_endofstorage = _first + n;
		}
	}
	void Reserve(size_t n)//保留
	{
		if (n > Capacity())
		{
			Expand(n);
		}
	}
	void PushBack(DataType x)//尾插
	{
		//if (_finish == _endofstorage)//查容
		//{
		//	if (Capacity() == 0)
		//	{
		//		Expand(3);//扩容
		//	}
		//	else
		//	{
		//		Expand(Capacity() * 2);
		//	}
		//}
		//*_finish = x;
		//_finish++;
		Insert(Size(), x);
	}
	void PopBack()//尾删
	{
		assert(_finish > _first);
		--_finish;
	}
	void Insert(size_t pos, DataType x)//在pos位置上插入x
	{
		assert(pos <= Size());
		if (_finish == _endofstorage)//查容
		{
			if (Capacity() == 0)
			{
				Expand(3);//扩容
			}
			else
			{
				Expand(Capacity() * 2);
			}
		}

		//搬移数据
		int end = Size() - 1;
		while (end >= (int)pos)
		{
			_first[end + 1] = _first[end];
			--end;
		}

		//放数据
		_first[pos] = x;
		++_finish;
	}
	void Erase(size_t pos)//删除位置pos上的数据
	{
		assert(pos < Size());

		size_t cur = pos;
		while (cur < Size()-1)
		{
			_first[cur] = _first[cur + 1];
			++cur;
			_finish--;
		}
	}
	size_t Find(DataType x)//查找x
	{
		size_t i = 0;
		for (i = 0; i < Size() - 1;i++)
		{
			if (_first[i] == x)
				return i;
		}
	}
	void print()
	{
		DataType* cur = _first;
		while (cur != _finish)
		{
			cout << *cur << " ";
			cur++;
		}
		cout << endl;
	}
private:
	DataType* _first;//指向内存空间(数组)起始的指针
	DataType* _finish;//指向数组最后的指针
	DataType* _endofstorage;//指向内存空间最后的指针
};

void TestVector()
{
	Vector v1;
	v1.PushBack(1);
	v1.PushBack(2);
	v1.PushBack(3);
	v1.PushBack(4);
	v1.print();

	v1.PopBack();
	v1.print();
	
	v1.Insert(2, 5);
	v1.print();

	v1.Erase(2);
	v1.print();

	cout << v1.Find(2) << endl;

	//拷贝构造
	Vector v2(v1);
	v2.print();

	//赋值运算符
	Vector v3;
	v3.PushBack(9);
	v3.print();
	v3 = v1;
	v3.print();
}

2、LinkList.h

#pragma once

#include<iostream>
using namespace std;
#include<assert.h>
//双向循环链表
typedef int DataType;

struct ListNode
{
	ListNode* _next;
	ListNode* _prev;

	DataType _data;

	ListNode(DataType x)
		:_data(x)
		, _next(NULL)
		, _prev(NULL)
	{}
};
class List
{
	typedef ListNode Node;
public:
	List()//构造函数
		:_head(new Node(DataType()))
	{
		_head->_next = _head;
		_head->_prev = _head;
	}
	List(const List & l)//拷贝构造
		:_head(new Node(DataType()))
	{
		//创建
		_head->_next = _head;
		_head->_next = _head;

		Node* cur = l._head->_next;
		while (cur != l._head)
		{
			PushBack(cur->_data);
			cur = cur->_next;
		}
	}
	List& operator=(List l)//赋值
	{
		/*Node* cur = l._head->_next;
		while (cur != l._head)
		{
		PushBack(cur->_data);
		cur=cur->_next ;
		}*/

		swap(_head, l._head);
		return *this;
	}
	~List()//析构函数
	{
		Node* cur = _head->_next;
		while (cur != _head)
		{
			Node* next = cur->_next;
			delete cur;
			cur = next;
		}
		delete _head;
		_head = NULL;
	}
	void PushBack(DataType x)//尾插
	{
		//Node* tail = _head->_prev;//找尾
		//Node* newnode = new Node(x);

		//tail->_next = newnode;
		//newnode->_prev = tail;

		//newnode->_next = _head;
		//_head->_prev = newnode;

		Insert(_head, x);
	}
	void PopBack()//尾删
	{
		Erase(_head->_prev);
	}
	void PushFront(DataType x)//头插
	{
		Insert(_head->_next, x);
	}
	void PopFront()//头删
	{
		Erase(_head->_next);
	}
	void Insert(Node* pos, DataType x)//在pos位置之前插入x
	{
		assert(pos);
		Node* cur = pos->_prev;
		Node* newnode = new Node(x);

		cur->_next = newnode;
		newnode->_prev = cur;
		newnode->_next = pos;
		pos->_prev = newnode;
	}
	void Erase(Node* pos)//删除pos位置上的数据
	{
		assert(pos != _head);

		Node* prev = pos->_prev;
		Node* next = pos->_next;

		delete pos;
		prev->_next = next;
		next->_prev = prev;

	}
	void print()
	{
		Node* cur = _head->_next;
		while (cur != _head)
		{
			cout << cur->_data << " ";
			cur = cur->_next;
		}
		cout << endl;
	}
private:
	Node* _head;//头指针
};
void TestList()
{
	List l1;
	l1.PushBack(1);
	l1.PushBack(2);
	l1.PushBack(3);
	l1.PushBack(4);
	l1.PushBack(5);
	l1.print();

	l1.PopBack();
	l1.print();

	l1.PushFront(0);
	l1.print();

	l1.PopFront();	
	l1.print();

	/*List l2(l1);
	l2.print();*/
}

3、test.cpp

#include "LinkList.h"
#include "Vector.h"

int main()
{
	//TestVector();//顺序表
	TestList();//链表

	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值