文章目录
(一) 动态链表
#include<iostream>
using namespace std;
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;
pre = p;
}
return head;
}
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;
p -> next = q;
}
void del(node* head ,int x)
{
node* p =head -> next;
node* pre = head;
while(p)
{
if(p -> data == x)
{
pre -> next = p -> next ;
free(p);
p = pre -> next;
}
else
{
pre = p;
p = p-> next;
}
}
}
int main()
{
int Arrray[5] = {1,2,3,4,5};
node * h = create(Arrray);
h = h->next;
while(h)
{
cout<<h -> data;
h = h-> next;
}
}
(二)静态链表
(1)静态链表组成
struct Node
{
int adress; //结点地址
typename data;//数据域
int next;//指针域
xxx;//结点的性质 不同题目不同设置
}node[maxn];
for(int i = 0 ; i < maxn ;i ++)
node[i].xxx = false;
初始化性质
int p = begin,count =0 ;
while(p != -1)
{
xxx =1 ;
count++;
p = node[p] -> next;
}遍历链表 在链表上的结点设为1 并统计结点数
bool cmp(Node a,Node b)
{
if(a.xxx == -1 || b.xxx == -1)
return a.xxx > b.xxx;排序 即将有效结点往前放
else
二级排序;根据题目要求
}
(2)静态链表例题
PAT A1032 Sharing (25分)
题意:给出两个链表,求首个公共结点
如果没有就输出-1
#include<iostream>
using namespace std;
const int maxn = 100000;
struct Node
{
char data;
int next;
bool flag;
}node[maxn];
int main()
{
for(int i = 0 ; i<maxn;i++)
node[i].flag = false;
int s1,s2,n;
cin>>s1>>s2>>n;
int address ,next;
char data;
for(int i = 0; i < n ; i++)
{
scanf("%d %c %d",&address,&data,&next);
node[address].data = data;
node[address].next = next;
}
int p ;
for(p =s1 ; p!=-1 ; p = node[p].next)
{
node[p].flag = true;
}
for(p = s2 ; p != -1 ; p = node[p].next)
{
if(node[p].flag == true) break;
}
if(p != -1)
printf("%05d\n",p);
else
cout<<-1;
}
1052 Linked List Sorting (25分)
题意:给出静态链表的结点与数值(可能存在不在链表上的结点)按照结点值以非递减的顺序/输出
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100000;
struct Node
{
int address,date,next;
bool flag;//flag 用来标记结点是否在链表
}node[maxn];
bool cmp(Node a,Node b)
{
if(a.flag==false || b.flag == false)
return a.flag > b.flag;
else
return a.date < b.date;
}//链表排序 首先将不在链表上的结点向后
//然后根据值排序 这一步需要结构体存地址
int main()
{
for(int i = 0; i < 。maxn ; i ++)
node[i].flag = false;//先标记为都不在链表上
int n,begin,address;
cin>>n>>begin;
for(int i = 0; i < n ;i++)
{
scanf("%d",&address);
scanf("%d%d",&node[address].date,&node[address].next);
node[address].address = address;
}
int count = 0 , p = begin;
for(p;p != -1 ; p = node[p].next)
{
node[p].flag = true;
count++;
}//遍历链表 并将结点标记为存在
sort(node,node + maxn ,cmp);
if(count ==0 )//可能有 没有结点的极端情况
cout<<"0 -1";
else
{
printf("%d %05d\n",count,node[0].address);
for(int i =0 ; i < count ; i++)
{
if(i != count - 1)
printf("%05d %d %05d\n",node[i].address,node[i].date,node[i+1].address);
else
printf("%05d %d -1",node[i].address,node[i].date);//最后一个单独处理
}
}
}
1074 Reversing Linked List (25分)
题意:给出一个静态链表 再给出k 按每k个翻转
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn =100000;
struct NODE
{
int address,data,next;
int rank1 ;//这题的要求是顺序 故rank1存放顺序
}node[maxn];
bool cmp(NODE a,NODE b)
{
return a.rank1 < b.rank1;//按排名排序 未在链表上的结点已赋值maxn
}
int main()
{
for(int i=0 ; i < maxn ; i ++)
node[i].rank1 = maxn;
int begin,n,k;
cin>>begin>>n>>k;
int address;
for(int i = 0; i < n;i++)
{
scanf("%d",&address);
scanf("%d%d",&node[address].data,&node[address].next);
node[address].address =address;
}
int p = begin , count =0 ;
for(p ; p!= -1 ; p = node[p].next)
{
node[p].rank1 = count ++;
}//计数
sort(node,node + maxn , cmp);
for(int i = 0 ; i < count / k ;i++)
{
reverse(node + i*k , node + i*k +k);
}每k个翻转
for(int i =0 ; i < count ; i ++)
{
if(i!= count -1)
printf("%05d %d %05d\n",node[i].address,node[i].data,node[i+1].address);
else
printf("%05d %d -1",node[i].address,node[i].data);
}
}
1097 Deduplication on a Linked Li/st (25分)
题意:给出静态链表 从第一个开始如果后面有绝对值相同的就剔除且保存分别输出
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 100000;
bool vis[maxn];
struct NODE
{
int address,data,next;
int order;//隐含条件是顺序 顺带判断结点是否在链表上
}node[maxn],nod[maxn];//分别存剔除后的 与 剔除的结点
bool cmp(NODE a,NODE b)
{
return a.order < b.order;
}//排序 把有用结点拉到前面来
int main()
{
for(int i = 0 ; i < maxn ; i++)
node[i].order = maxn;//初始化
int begin,n;
cin>>begin>>n;
int address;
for(int i = 0 ; i < n;i++)
{
scanf("%d",&address);
scanf("%d%d",&node[address].data,&node[address].next);
node[address].address = address;
}
int count =0 ;
for(int p = begin ; p != -1 ; p = node[p].next)
{
node[p].order = count++;
}//统计有效的结点数
sort(node,node+maxn,cmp);
int index=0;
for(int i = 0 ; i < count ;i++)
{
if(vis[abs(node[i].data)] ==0)
{
vis[abs(node[i].data)]= 1;
}
else
{
node[i].order = maxn;
nod[index++] = node[i];
}
}//剔除操作 除掉的顺序记为maxn
sort(node,node+maxn,cmp);
for(int i = 0 ; i <count - index;i++)
{
if(i != count - index -1)
printf("%05d %d %05d\n",node[i].address,node[i].data,node[i+1].address);
else
printf("%05d %d -1\n",node[i].address,node[i].data);
}
for(int i = 0 ;i < index ;i++)
{
if(i != index -1)
printf("%05d %d %05d\n",nod[i].address,nod[i].data,nod[i+1].address);
else
printf("%05d %d -1\n",nod[i].address,nod[i].data);
}
}