作为一名程序员,大部分都知道:“好的程序 = 合适的数据结构 + 算法”。由于教学计划的设计,本来在大三的时候开设的数据结构课程,我们这一届放在了大一,在C语言之后学习。现在回想起来,当时听得云里雾里,似懂非懂的。
上个寒假(大三的上学期),自己已经解除了很多种高级编程语言了,也学习到很多的编程知识。自己在编程这条路上走得越久,越觉得合适的数据结构的重要性。没有最好的,只有最合适的......我们要根据对应的问题来设计相应的、适合这个问题的数据结构。一个好的数据结构,会使得整个程序逻辑清楚、效率高效。鉴于以上的因素,我将自己那本很久未动过的《数据结构》C语言版的带回家里,决定在家里研读此秘笈,修炼自己的“内功”。
下面给大家分享一个问题,展示如何使用数据结构中的知识,来设计程序:
针对这个问题,刚开始我想用数组来实现,但是后来想想:如果有很多个界面时,每次点击之后,界面的顺序就要重新排序(将点击的那个界面置于最顶层,而其他的界面相对顺序是不变的)。如果界面有很多,存储在数组中,考虑最坏的情况:点击最底层的界面n,那么从第一个到n-1界面,都要向后 移动一个单位。当问题的规模很大的时候,再使用数组处理的话,效果很不理想。最后想到,这个问题有个很好的解决办法:链表。当你点击x页面时,就将x页面对应的结点(Node),挪动到链表头就行,同时将后续的结点重新连接起来。上述对链表的操作过程,分解成两部分:1.(查找)遍历链表找到点击坐标对应的那个页面;2.(在链表头插一个结点)将这个x页面对应的节点置于链表头。
下面附上C语言实现的代码(已经调试通过了):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
int x1,x2,y1,y2,position;
}Data;
typedef struct Node
{
Data nodeData;
struct Node* nextNode;
}CLType;
typedef struct
{
int x,y;
}ClickData;
int n,m,result; //其中n为页面的个数 m为点击的次数
//追加结点函数
CLType* CLAddFirst(CLType* head,Data nodeData)
{
CLType *node;
if(!(node = (CLType*)malloc(sizeof(CLType))))
{
printf("申请内存资源失败!\n");
return NULL;
}
else
{
node->nodeData = nodeData;
node->nextNode=head;
head = node;
return head;
}
}
CLType* CLDeleteSortNode(CLType* head,ClickData testData)
{
CLType *node,*htemp,*deleted;
int i;
htemp = head;
node = head;
if((testData.x >= head->nodeData.x1) && (testData.x <= head->nodeData.x2) && (testData.y >= head->nodeData.y1) && (testData.y <= head->nodeData.y2))
{
result = head->nodeData.position;
return head; //所点击的坐标就是最上面的页面中的坐标
}
for(i = 1; i <= n; i++) //所点击的坐标不是最上面的页面中的坐标
{
if((testData.x >= htemp->nodeData.x1) && (testData.x <= htemp->nodeData.x2) && (testData.y >= htemp->nodeData.y1) && (testData.y <= htemp->nodeData.y2))
{
deleted = node->nextNode;
node->nextNode = htemp->nextNode;
deleted->nextNode = head; //使得deleted指向头指针所指的结点
head = deleted;
result = head->nodeData.position;
return head;
}
else
{
node = htemp;
htemp = htemp->nextNode;
}
}
result = 0;
return head;
}
int CLLength(CLType *head) //求得链表的长度
{
CLType *htemp;
int Len=0;
htemp = head;
while(htemp)
{
Len++;
htemp=htemp->nextNode;
}
return Len;
}
void CLAllNode(CLType *head) //遍历链表
{
CLType *htemp;
Data nodeData;
htemp = head;
printf("当前链表共有%d个结点。链表所有数据如下: \n",CLLength(head));
while(htemp)
{
nodeData = htemp->nodeData;
printf("结点(%d,%d,%d,%d,%d)\n",nodeData.position,nodeData.x1,nodeData.y1,nodeData.x2,nodeData.y2);
htemp=htemp->nextNode;
}
}
int main(int argc, char *argv[])
{
CLType *node,*head = NULL;
Data nodeData;
ClickData testData;
int i;
scanf("%d",&n);
scanf("%d",&m);
int a[m+1];
for(i = 1; i <= n; i++)
{
scanf("%d%d%d%d",&nodeData.x1,&nodeData.y1,&nodeData.x2,&nodeData.y2);
nodeData.position = i;
head = CLAddFirst(head,nodeData);
}
CLAllNode(head);
for(i = 1; i <= m; i++)
{
scanf("%d%d",&testData.x,&testData.y);
head = CLDeleteSortNode(head,testData);
a[i] = result;
}
for(i = 1; i <= m; i++)
{
if(a[i] != 0)
{
printf("%d",a[i]);
}
else
{
printf("%s","IGNORED");
}
}
return 0;
}
截图证明: