用map和链表实现大量数据的有序的插入和查找

 对于大量数据的插入和查找,我们应该如何选择数据结构呢?

思路:

我们知道链表插入快,但是查找慢,map查找快,但是无序,想要有序的查找和插入,那就把两者结合起来使用。

链表:手写一些函数对链表进行基本的插入和删除,每次插入完成后需要更新map。

map:  map用来保存每个插入点的指针,用map查找插入点的指针,然后直接插入。map的各种操作的时间复杂度都是O(lgN)。

插入函数:

struct Node* inserter(struct Node *p,int key,int i) //把key插入到的前面 ,0插入到p的前,1后 
{
	struct Node *now;
	now=(struct Node*)malloc(sizeof(struct Node));
	now->data=key;
	if(i==0) //插入到前面 
	{
		now->prime=p->prime;
		p->prime->next=now;
		now->next=p;
		p->prime=now;
		return now;
	}
	else
	{
		now->prime=p;
		now->next=p->next;
		if(p->next!=NULL)
			p->next->prime=now;
		p->next=now;
		return now;
	}
    //返回的now指针用来更新map
}

 返回的now指针用来更新map

map:

#include<map>  //记得加头文件

map<int,struct Node*> m;
struct Node *head,*now,*next;
	head=(struct Node*)malloc(sizeof(struct Node));
	head->prime=NULL;
	head->data=-1;
	now=(struct Node*)malloc(sizeof(struct Node));//第一个 
	head->next=now;
	now->next=NULL;
	now->data=1;
	now->prime=head;
	m[1]=now; //把第一个数的指针保存

题目练习

AC代码(后面有更好的思路):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<map> 
#define Max 100010
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
int live[Max]; //记录是否被删除 
struct Node{
	int data;
	struct Node* next;
	struct Node* prime;
};
struct Node* inserter(struct Node *p,int key,int i) //把key插入到的前面 ,0前,1后 
{
	struct Node *now;
	now=(struct Node*)malloc(sizeof(struct Node));
	now->data=key;
	if(i==0) //插入到前面 
	{
		now->prime=p->prime;
		p->prime->next=now;
		now->next=p;
		p->prime=now;
		return now;
	}
	else
	{
		now->prime=p;
		now->next=p->next;
		if(p->next!=NULL)
			p->next->prime=now;
		p->next=now;
		return now;
	}
}
void show(struct Node *q) //显示还有表内的人 
{
	struct Node *p=q;
	p=p->next;
	while(p!=NULL) //输出格式 ,空格 
	{
		if(!live[p->data])
		{
			printf("%d",p->data);  //最后记得调整格式问题
			break;
		}
		p=p->next;
	}
	p=p->next;
	while(p!=NULL)
	{
		if(!live[p->data])
		{
			printf(" %d",p->data);  //最后记得调整格式问题 
		}
		p=p->next;
	}
	printf("\n");
}
int main()
{
	map<int,struct Node*> m;
	struct Node *head,*now,*next;
	head=(struct Node*)malloc(sizeof(struct Node));
	head->prime=NULL;
	head->data=-1;
	now=(struct Node*)malloc(sizeof(struct Node));//第一个 
	head->next=now;
	now->next=NULL;
	now->data=1;
	now->prime=head;
	m[1]=now; //第一个 
	int num,j,n,M;
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		scanf("%d%d",&num,&j);
		now=m[num];//要插入的地方 
		m[i]=inserter(now,i,j);
	}
	scanf("%d",&M);
	memset(live,0,sizeof(live));
	for(int i=0;i<M;i++)
	{
		scanf("%d",&num);
		live[num]=1;//需要删除的同学 
	}
	show(head);
	return 0;
}

(辛苦的写完代码后,发现有些时候可以只用线性表就能完成快速的查找.....)

当插入的数据类型为整型的时候,我们用如下结构体来保存数据:

struct Node{
    int data;
    int prime; //指向前面一个数的位置
    int next;  //指向后面一个数的位置
}node[100010];

我们可以直接利用节点的数据,达到直接访问下一个节点,每次插入完成后像链表一样调整前面数据就好,查找、插入的时间复杂度都是O(1)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值