數據結構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;
}

學到了很多!自己的不足還是很多

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章