数据结构1-2Zuma

这道题主要是链表,所以我又回去翻了一遍链表。。后来还是借鉴大神的思想才能做出来

复杂度就是O(n),链表插入删除时O(1),查找是O(n),关键是连锁删除的部分,首先插入后若有可能删除最多只有五个,所以在五个之中遍历,消除后最多只有四个能消除,座椅范围减少为四,贴代码:

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<cstring>
using namespace std;
const int maxLength = 10005;
struct Node //链表所需struct链表,有只想之前的指针和指向后面的指针(方便回溯,一开始我也只是有向后的指针)
{
char Data;
Node* next;
Node *front;
};
class list
{


public:
Node *head; //借鉴大神的思想,设置标杆,所有的处理都在标杆内,简化处理内容
Node *tail;
list(){ };
void insertList(int location, char aData);
void deleteList(int location);
void outputList();
void creat(char *a , int n );

};
void list::creat(char *a , int n)
{
head = (Node *)malloc(sizeof(Node));//这里是重点,首先要为head和tail指针动态分配内存。
tail = (Node *)malloc(sizeof(Node));
int i ;
Node *pt = head;
tail->front = head;
head->next = tail;
head->front = NULL;
tail->next = NULL;
head->Data = '-';
tail->Data = '-';


for ( i = 0 ;i < n ;i++)//创建链表,输入是一个字符数组,顺序插入list内
{
Node *s;
s = (Node *)new(Node);
s -> Data = a[i];
s -> front = pt;
s -> next = pt -> next;
pt->next->front = s;
pt->next = s;
pt = s;
}
}
void list::insertList( int location, char adata )
{ //插入这里学到一个技巧,就是INT I =-1;WHILE(I--<M),这样就能找到第m个位置
Node *p, *s;
s = (Node *)new(Node);
p = head;
int i = -1;
while(i++ < location)
{
p = p->next;
}
s -> Data = adata;
s -> next = p;
s -> front = p->front;
p -> front->next = s;
p -> front = s;



}
void list::deleteList(int location) //delete函数是重点,
{
Node *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL,
*p = head;
Node *begin = head, *end = tail;
bool flag = true;
int i = -1,repeat;
while(i++ < location - 2)//由于location是插入的位置,能消除的部分至多是从location-2开始,所以p先移动到

//location-2
p = p->next;
begin = p; //循环的范围就是(p,p+4),因此把end挪到p+4
end = p;
i = 0;
while(i++ < 4 && end->next != tail)
end = end -> next;
while(flag && p != tail)//这里判定是否循环,当上一次存在消除,且当前指针未到tail时,说明可以继续遍历

  //刚才重新写的时候发现的边界问题,为什么这里是p != tail呢?

  //我们先看end,由于之前的限定,end 最多为tail之前的最后一个元素。而p最多为location-2,也就是说不为tail,而且end肯定先于p达到tail,由下面的条   //件,p是先判定在指向下一个,也就是说,p要满足=end的情况,所以要包含tail之前最后一个元素,所以是p != tail

while
{
flag = false; //先置false
repeat = 1;
while(p != end)//判断重复个数,分为三四,然后删除
{
p = p->next;
if(p->front->Data == p->Data)
repeat++;
else
repeat = 1;


if (repeat ==3)
{
flag = true;
if (p->Data == p->next->Data)
{
repeat++;
p = p->next;
}
if (repeat == 3)
{
p3 = p;
p2 = p3->front;
p1 = p2->front;
p3->next->front = p1->front ; 
p1->front->next = p3->next;
delete p1,p2,p3;
p = p->next;
}
else
{
p4 = p;
p3 = p4 -> front;
p2 = p3 -> front;
p1 = p2 -> front;
p4->next->front = p1->front ; 
p1->front->next = p4->next;
delete p1, p2, p3, p4;
p = p->next;
}
break;
}
}
if (flag && p != tail)//这里是删除后进入下一次删除前的设置,将begin前一两个,end后以一个,总共四个范围,然后p从头遍历
{
begin = p;
end = p;
i = 0;
while(i++ < 2&& (begin->front != head))
begin = begin ->front;
i = 0;
while(i++ < 1&& (end->next != tail))
end = end->next;
p = begin;
}


}
}


void list::outputList()
{
Node *p = head->next;
if (p == tail)
printf("-");
else
{
while(p->next != NULL)
{
printf("%c",p->Data);
p = p->next;
}
}
printf("\n");


}




int main(){
char s[maxLength;
list A;
int n;
A.head = NULL;
gets(s);

scanf("%d\n",&n);
A.creat(s,strlen(s));
while(n--)
{
int m;
char ch;
scanf("%d",&m);
do{
ch = getchar();
}while(!((ch >= 'A') && (ch <= 'Z')));
A.insertList(m,ch);
A.deleteList(m);
A.outputList();
}
return 0;
}

学到了很多!自己的不足还是很多

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值