数据结构与算法(第一章)

目录

前言

一、什么是数据结构?

二、线性链表的实现

1.单链表

操作实现:

 2.双链表

3.循环链表

三、链表的应用

 约瑟夫环问题


前言

本系列文章记录数据结构的概念类型与实现,附有相关编程练习题,可供日后复习。

本章包括基本概念与线性链表的实现。


一、什么是数据结构?

数据结构即研究数据与数据之间的关系。包括数据的逻辑结构,存储结构与操作实现。

数据的逻辑结构是从逻辑上观察数据与数据之间的关系。

 数据的存储结构是逻辑结构在计算机存储结构中的具体实现。

包括:顺序 链式 索引和散列。

二、线性链表的实现

virtual bool insert ( const Elem& )=0;  参数用const修饰表示是常量不可作为左值并且改变;参数为引用表示共用地址。

1.单链表

C++中采用结构体的标准定义"struct Node{};"这种形式,定义变量可以直接使用Node node1这种形式区别在于C++中的“struct Node{} node1;”是在定义结构体的同时定义的结构体变量node1,而不是结构体的等价形式,因此不能用node1来定义新变量。
————————————————
原文链接:https://blog.csdn.net/u011305167/article/details/82782688

template<class T>
struct Node
{
	T data;
	Node*next;
};
template<class T>
class Link
{
	Node<T>*head;
    Node<T>*tail;
    Node<T>*curr;
public:
	Link()
	{
		head=tail=curr=new Node<T>;
		head->next=NULL;
	}
	~Link()
	{
		while(head)
		{
			Node<T>*curr=head;
			head=head->next;
			delete curr;
		}
	}
	bool get(T &e);//得到当前位置节点的data值 
	void insert(T elem);//在curr后插入节点 
	bool isempty(){return head->next==NULL; }
	bool delet(T &e);//删除curr后的节点 
	Node<T>*locate(T e);//根据data值定位节点 
	bool setpos(int pos);//移动curr到任意位置 	
};
       

操作实现:

template<class T>
bool Link<T>::get(T&e)
{
	if(head->next==NULL)
	return false;
	e=curr->data;
	return true;
}
template<class T>
void Link<T>:: insert(T e)
{
	Node<T>*node=new Node<T>;
	node->data=e;
	node->next=curr->next;
	curr->next=node;//如在尾节点后插入需改变tail 
}
template<class T>
bool Link<T>::delet(T &e)
{
	if(curr->next==NULL)
	return false;
	Node<T>*node=curr->next;
	e=node->data;
	curr->next=node->next;
	delete node;
	return true;
}
template<class T>
Node<T>* Link<T>::locate(T e)
{
	curr=head->next;
	while(curr->data!=e&&curr)
	curr=curr->next;
	return curr;
}

 2.双链表

改动部分:

	template<class T>
struct Node
{
	T data;
	Node*prev;
	Node*next;
};
template<class T>
class DLink
{
	Node<T>*head;
    Node<T>*tail;
    Node<T>*curr;
public:
	DLink()
	{
		head=tail=curr=new Node<T>;
		head->next=NULL;
		head->prev=NULL;
	}
	~DLink()
	{
		while(head)
		{
			Node<T>*curr=head;
			head=head->next;
			delete curr;
		}	
	}

 插入和删除操作:

template<class T>
void DLink<T>:: insert(T e)
{
	Node<T>*node=new Node<T>;
	Node<T>*nextptr=curr->next;
	node->data=e;
	node->next=nextptr;
	node->prev=curr;
	nextptr->prev=node;
	curr->next=node;
	//如在尾节点后插入需改变tail 
}
template<class T>
bool DLink<T>::delet(T &e)//删除curr节点 
{
	if(curr==NULL||head->next==NULL)
	return false;
	Node<T>*temp=curr;
	curr->prev->next=curr->next;
	curr->next->prev=curr->prev;
	e=curr->data;
	curr=curr->next;
	delete temp;
	return true;
}

3.循环链表

template<class T>
class CLink
{
	Node<T>*head;
    Node<T>*tail;
    Node<T>*curr;
public:
	CLink()
	{
		head=tail=curr=new Node<T>;
		head->next=head;
	}
	~CLink()
	{
		while(head->next!=head)
		{
			Node<T>*curr=head->next;
			head->next=curr->next;
			delete curr;
		}
		delete head;
	}
bool isempty(){return head->next!=head; }
}

以上为单循环链表,双循环链表以此类推。 

三、链表的应用

 约瑟夫环问题

#include<iostream>
using namespace std;
struct Node
{
	int data;
	Node*next;
};
class CLink
{
public: 
	Node*head;
    Node*curr;
	CLink(int n)
	{
		head=curr=new Node;
		head->data=n;
		head->next=head;
	}
	void insert(int e);
};
void CLink:: insert(int e)
{
	Node*node=new Node;
	node->data=e;
	node->next=curr->next;
	curr->next=node;
}
int main()
{
    int n;
	cin>>n;	
	CLink l(1);
	for(int i=n;i>=2;i--)
	{
		l.insert(i);
	}
	int m;
	cin>>m;
	Node*pre;
	for(int i=0;i<n;i++)
	{
		for(int j=1;j<m;j++)
		{
			pre=l.curr;
			l.curr=l.curr->next;
		}
		cout<<"第"<<i+1<<"次出列的人是"<<l.curr->data<<"号"<<endl;
		m=l.curr->data;
		pre->next=l.curr->next;
		delete l.curr;
		l.curr=pre->next;
	}	
}

商品链表的更新

typedef struct Node{...} Node,*Llist;

typedef  struct Node {......}Node,*Llist;

struct Node {......}Node,*Llist相当于int’ a,int’ *b; 

typedef说明a是自定义结构的类,b是自定义结构指针的类,a,b都可以定义对象。

#include<iostream>
using namespace std;
struct Node
{
    int no,num;
    Node*next;	
};
void free(Node*p)
{
	while(p->next)
	{
		Node*curr=p->next;
		p->next=curr->next;
		delete curr;
	}
}
void update(Node*l1,Node*l2)
{
	Node*p=l1;
	while(l2->next!=NULL)
	{
		Node*q=l2->next;
		while(p->next->no<q->no&&p->next)
		p=p->next;
		if(!p->next)
		{
		    p->next=q;
		    free(l2) ;
		    return;
		}
		l2->next=q->next;
		if(p->next->no==q->no)
		{
			p->next->num+=q->num;			
			delete q;
		}
		else
		{
			q->next=p->next;
			p->next=q;
			p=q;
		}	
	 } 		
	delete l2;
	return;
}

int main()
{
	Node*lyet,*ladd;
    update(lyet,ladd);
}

 最后一个else代码跟书上的不同,如果发现我有错希望在评论区留言。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值