【PAT】第七章 数据结构专题

第七章 数据结构专题

7.3 链表处理

7.3.1 链表的概念

不连续存储。
结点=数据域+结点域。

struct Node{
	typename data; 	//数据域 
	Node* next; 	//指针域 
};
链表分类

头结点head:数据域不放任何东西,指针域指向第一个数据域有内容的结点。

根据链表有没有头结点可以分为带头结点的链表和不带头结点的链表。

7.3.2 malloc函数或new运算符为链表节点分配内存空间

1. malloc函数

头文件:#include <stdlib.h>

typename * p=(typename*)malloc(sizeof(typename)); 	//返回指向开辟空间的指针。申请失败返回空指针NULL。

int* p=(int*)malloc(sizeof(int));
node* p=(node*)malloc(sizeof(node));
2. new运算符
typename* p=new typename;

int* p=new int;
node* p=new node;
3. 内存泄漏
free函数

头文件:#include <stdlib.h>

释放指针变量p指向的内存空间,将指针变量p指向空地址NULL

free(p);
delete运算符

释放指针变量p指向的内存空间,将指针变量p指向空地址NULL

delete(p);

7.3.3 链表的基本操作

1. 创建链表
#include <cstdio>
#include <cstdlib>

struct node{
	int data;
	node* next;
};

node* create(int array[])
{
	node *p,*pre,*head;
	head=new node;
	head->next=NULL; 	//头结点不需要数据域 
	pre=head;
	for(int i=0;i<5;i++)
	{
		p=new node;
		p->data=array[i]; 	//当前指针 
		p->next=NULL;
		pre->next=p; 	//前一个指针->next=当前指针 
		pre=p;
	}
	return head;
}
int main()
{
	int array[5]={5,2,3,6,1};
	node* L=create(array);
	L=L->next; 	//第一个结点开始(非头结点)
	while(L!=NULL)
	{
		printf("%d",L->data);
		L=L->next;
	 } 
	 return 0;
 } 
2. 查找元素个数

从第一个结点开始顺序遍历,查找元素。

int search(node*head,int x)
{
	int cnt=0;
	node* p=head->next; 	//从第一个结点开始
	while(p!=NULL)
	{
		if(p->data==x)
			cnt++;
		p=p->next;
	}
	return cnt;
}
3. 插入元素

在给定位置插入一个结点。

void insert(node* head,int pos,int x)
{
	node* p=head;
	for(int i=0;i<pos-1;i++) 	//插入的前一个结点 
	{
		p=p->next;
	}
	node* q=new node;
	q->data=x;
	q->next=p->next; 	//先更新新节点的next
	p->next=q; 	//再更新前一个结点的next
}
4. 删除元素

删除链表上所有值为x的结点。
结点p枚举结点,结点pre记录了当前结点的前一个结点。

void del(node* head,int x)
{
	node* p=head->next;
	node* pre=head;
	while(p!=NULL)
	{
		if(p->data==x)
		{
			pre->next=p->next;
			deletr(p);
			p=pre->next;
		}
		else
		{
			pre=p;
			p=p->next;
		}
	}
}

7.3.4 静态链表

实现原理
hash。
建立结构体数组,令数组下标直接表示结点的地址,达到直接访问数组中的元素就能访问结点的效果。不需要头结点。

struct Node{
 	typename data; 	//数据域 
 	int next; 	//指针域 
}node[size];

例题

【例】1097 Deduplication on a Linked List (25 分)

remove v.删除
Deduplication n.重复数据删除
absolute value 绝对值
duplicated a.重复的

ATTENTION

  • 注意绝对值相等就要remove。

修改前:

//duplicated
#include <cstdio>
#include <vector>
#include <cmath>
#include <cstdlib>
using namespace std;

bool key[10010]={0};
vector<int> ans,rem;
struct Node{
	int adr;
	int key;
	int next;
	int nextIdx;
	Node()
	{
		next=-1;nextIdx=-1;
	}
}node[100010];

int main()
{
	int start=-1,startIdx=-1,n;
	scanf("%d %d",&start,&n);
	for(int i=0;i<n;i++)
	{
		int adr,key,next;
		scanf("%d %d %d",&adr,&key,&next);
		node[i].adr=adr;
		node[i].key=key;
		node[i].next=next;
		if(adr==start)
			startIdx=i;
	}
	int cur=startIdx;
	while(node[cur].next!=-1)
	{
		for(int i=0;i<n;i++)
		{
			if(node[i].adr==node[cur].next)
			{
				node[cur].nextIdx=i;
				cur=i;
			}
		}
	}
	cur=startIdx;
	int p=-1,q=-1;
	while(cur!=-1)
	{
		if(key[abs(node[cur].key)]==0)
		{
			ans.push_back(cur);
			key[abs(node[cur].key)]=1;
			if(p!=-1)
				node[p].next=node[cur].adr;
			p=cur;	
		}
		else
		{
			rem.push_back(cur);
			if(q!=-1)
				node[q].next=node[cur].adr;
			q=cur;
		}
		cur=node[cur].nextIdx;
	}
	if(ans.size()>0) 	//这地方不判断会指向非法内存 
		node[ans[ans.size()-1]].next=-1;
	if(rem.size()>0) 	//这地方不判断会指向非法内存 
		node[rem[rem.size()-1]].next=-1;
	for(int i=0;i<ans.size();i++)
	{
		if(node[ans[i]].next==-1)
			printf("%05d %d %d\n",node[ans[i]].adr,node[ans[i]].key,node[ans[i]].next);
		else
			printf("%05d %d %05d\n",node[ans[i]].adr,node[ans[i]].key,node[ans[i]].next);
	}
	for(int i=0;i<rem.size();i++)
	{
		if(node[rem[i]].next==-1)
			printf("%05d %d %d\n",node[rem[i]].adr,node[rem[i]].key,node[rem[i]].next);
		else
			printf("%05d %d %05d\n",node[rem[i]].adr,node[rem[i]].key,node[rem[i]].next);
	}
	return 0;
}

修改后:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值