在本节中,将会介绍关于数据结构的基本类型,如线性表,堆栈和队列node
在数据结构中,线性表是最多见也是使用最频繁的基本数据结构,它能够经过数组实现或者链表实现,下面给出两种不一样的实现代码。git
//implemented by array #include<stdio.h> #include<stdbool.h> #define MAXSIZE 5 #define ElementType int typedef struct LNode* List; struct LNode { ElementType Data[MAXSIZE]; int last; }; //make a empty arraylist List makeEmpty() { List ptrl; ptrl = (List)malloc(sizeof(struct LNode)); ptrl->last = 0; return ptrl; } //find element by value int findInValue(ElementType value,List ptrl) { int i = 0; while (i <= ptrl->last) { if (value == ptrl->Data[i++]) { return i-1; } } return -1; } //find element by index ElementType findInIndex(int index ,List ptrl) { if (index > ptrl->last) { return -1; } else { return ptrl->Data[index]; } } //check the arraylist is full bool isFull(List ptrl) { if (ptrl->last==MAXSIZE) { return true; } else { return false; } } //check the arraylist is empty bool isEmptry(List ptrl) { if (ptrl->last == 0) { return true; } else { return false; } } //insert by index void insert(ElementType value, int index, List ptrl) { //if list is full,wring! if (isFull(ptrl)) { printf("warning: now this arraylist is full,can't insert anything."); return; } else if (index<0||index>ptrl->last) { printf("warning: the insert position is invalid."); return; } else { //if index less than last,need move all the elements between index and last back one place for (int i = ptrl->last; i > index; i--) { ptrl->Data[i] = ptrl->Data[i - 1]; } ptrl->Data[index] = value; ptrl->last++; } } //delete element by index void delete(int index, List ptrl) { if (isEmptry(ptrl)) { printf("warning: this position isn't exists."); return; } else if(index<0||index>=MAXSIZE){ printf("warning: ArrayIndex invalid."); return; } else { for (int i = index; i < ptrl->last; i++) { ptrl->Data[i] = ptrl->Data[i + 1]; } ptrl->last--; } } //printlist void printList(List ptrl) { for (int i = 0; i < ptrl->last; i++) { printf("%d ", ptrl->Data[i]); } printf("\n"); } //test code int main(void) { //make empty list List L = makeEmpty(); // for (int i = 1; i < 6; i++) { insert(i, 0, L); printList(L); } printf("index of %d is %d\n", 3, findInIndex(3,L)); printf("the %d in %d\n", 1, findInValue(1,L)); for (int i = 1; i < 6; i++) { delete(0, L); printList(L); } }
//implemented by linklist #include<stdio.h> #include<stdbool.h> #include "malloc.h" typedef struct LNode* List; #define ElementType int struct LNode { ElementType Data; List Next; }; //get link list length,the empty table has a header, the default length is 0 int length(List ptrl) { List temp = ptrl; int len = 0; while (temp->Next) { temp = temp->Next; len++; } return len; } //make an empty linked list,generate an empty header(length is 1) List makeEmpty() { List ptrl; ptrl = (List)malloc(sizeof(struct LNode)); ptrl->Next = NULL; return ptrl; } //check the linklist is empty bool isEmpty(List ptrl) { if(length(ptrl) == 0) { return true; } else { return false; } } //find element by index,the index of the header is 0,(index>=0) List findInIndex(int index, List ptrl) { int i = 0; List temp = ptrl; while (temp!=NULL&&i<index) { temp = temp->Next; i++; } if (i == index) { return temp; } else { return NULL; } } //find element by value List findInValue(ElementType value, List ptrl) { List temp = ptrl; while (temp) { if (temp->Data == value) { break; } temp = temp->Next; } return temp; } //Insert element at specified position(1-the last) List insert(ElementType value,int index,List ptrl) { List temp = findInIndex(index-1,ptrl); if (temp==NULL) { printf("wanring: the index is invalid."); return NULL; } else { List newLNode = (List)malloc(sizeof(struct LNode)); newLNode->Data = value; if (temp->Next==NULL) { temp->Next = newLNode; newLNode->Next = NULL; } else { newLNode->Next = temp->Next; temp->Next = newLNode; } return ptrl; } } //print list void printList(List ptrl) { if (isEmpty(ptrl)) { return; } List temp = ptrl->Next; while (temp) { printf("%d ", temp->Data); temp = temp->Next; } printf("\n"); } //Delete the node at the specified position(0<index<last) List delete(int index,List ptrl) { if (isEmpty(ptrl)) { printf("the linked list has been empty."); return ptrl; } List temp = findInIndex(index - 1,ptrl); List tempNext= temp->Next; if (temp->Next->Next != NULL) { temp->Next = tempNext->Next; } else { temp->Next = NULL; } free(tempNext); return ptrl; } int main(void) { List L = makeEmpty(); L = insert(3, 1, L); printList(L); L = insert(5, 1, L); printList(L); L = insert(1, 1, L); printList(L); L = delete(2, L); printList(L); printf("%d", length(L)); }
在经过链表实现线性表时,常见的作法是创建一个空表头不存储任何数据,当表头的下一个指向为空时,线性表为空,这样作虽然会在内存上有一点的浪费,但操做起来相对更方便。算法
对于一个堆栈,他特有的性质是先进后出,后进先出,就像把盘子叠在一块儿,最后放在上面的盘子会被更早用到。一样能够用数组实现或是链实现。数组
#include<stdio.h> #include<stdbool.h> #include "malloc.h" typedef struct SNode *Stack; #define MAXSIZE 10 #define ElementType int struct SNode { ElementType Data[MAXSIZE]; //top is the number of elements int top; }; //make a empty stack Stack makeEmpty() { Stack S = (Stack)malloc(sizeof(struct SNode)); S->top = 0; } //check is empty bool isEmpty(Stack ptrs) { if (ptrs->top==0) { return true; } return false; } //check is full bool isFull(Stack ptrs) { if (ptrs->top==MAXSIZE) { return true; } return false; } //push element void push(ElementType value, Stack ptrs) { if (isFull(ptrs)) { printf("the stack has been full."); return ; } ptrs->Data[ptrs->top++] = value; } //pop ElementType pop(Stack ptrs) { if (isEmpty(ptrs)) { printf("the stack has been empty."); return; } return ptrs->Data[--ptrs->top]; } int main() { Stack S = makeEmpty(); //push 1,2,...5 for (int i = 1; i < 6; i++) { push(i, S); } //pop all elements while (!isEmpty(S)) { printf("%d ", pop(S)); } return 0; }
对于用链表构造一个堆栈,那么栈顶应该是在链表的尾部仍是头部?答案是均可以,栈顶在头部的话,入栈时,由于咱们有空头节点的缘由,直接创建一个新节点保存元素,将新节点的\(Next\)指向空头结点的\(Next\),再把空头结点的\(Next\)指向新节点。出栈用一个临时指针(\(temp\))指向空头结点的\(Next\),再将空头结点的\(Next\)指向\(temp\)指向节点的\(Next\),这样就将须要抛出的元素从链表中取出,保存元素值,释放掉该节点(\(free\)),返回要抛出的元素;栈顶在尾部的话,入栈时,由于咱们有空头节点的缘由,无需考虑链表空和不空状态下的不一样操做,直接用指针遍历到最后一个元素,创建一个新起点保存的元素,而后把它接在列表的末尾。出栈时,咱们能够遍历的方法,直到\(ptrs->Next->Next\)为\(NULL\)时,此时\(ptrs\)所指的正好是栈顶的第二个元素,保证了不会出现抛出后没法回去(若是直接遍历到栈顶元素会没法找到栈顶元素的上一个节点,没法将其的\(Next\)设为\(NULL\),这将会致使错误),用一个临时指针指向\(ptrs->Next\)(也就是栈顶元素的节点),保存元素的值,而后释放掉该节点,将\(ptrs\)指向的节点\(Next\)设为\(NULL\),返回须要抛出元素的值。(注意:栈顶在尾部,堆栈必定要有空头节点,不然实现起来将会极其困难复杂)数据结构
虽然栈顶在头部或者尾部均可以,但仍是建议栈顶设置在在头部(从算法上看在头部相比在尾部会更快)。less
//The top of the stack is at the head of the list #include<stdio.h> #include<stdbool.h> #include "malloc.h" typedef struct SNode* Stack; #define ElementType int struct SNode { ElementType Data; Stack Next; }; //get link stack length,the empty stack has a header, the default length is 0 int length(Stack ptrs) { Stack temp = ptrs; int len = 0; while (temp->Next) { temp = temp->Next; len++; } return len; } //make an empty linked Stack,generate an empty header(length is 1) Stack makeEmpty() { Stack ptrs; ptrs = (Stack)malloc(sizeof(struct SNode)); ptrs->Next = NULL; return ptrs; } //check the linklist is empty bool isEmpty(Stack ptrs) { if (length(ptrs) == 0) { return true; } else { return false; } } //push Stack push(ElementType value, Stack ptrs) { Stack newLNode = (Stack)malloc(sizeof(struct SNode)); newLNode->Data = value; newLNode->Next = ptrs->Next; ptrs->Next = newLNode; return ptrs; } //pop ElementType pop(Stack ptrs) { if (isEmpty(ptrs)) { printf("the Stack has been empty."); return -1; } Stack temp = ptrs->Next; ElementType value = temp->Data; ptrs->Next = temp->Next; free(temp); return value; } //print Stack void printStack(Stack ptrs) { if (isEmpty(ptrs)) { return; } Stack temp = ptrs->Next; while (temp) { printf("%d ", temp->Data); temp = temp->Next; } printf("\n"); } int main() { Stack S = makeEmpty(); for (int i = 0; i < 5; i++) { ElementType value; scanf_s("%d", &value); S = push(value, S); } printStack(S); while (!isEmpty(S)) { printf("%d ", pop(S)); } return 0; }
//The top of the stack is at the tail of the list #include<stdio.h> #include<stdbool.h> #include "malloc.h" typedef struct SNode* Stack; #define ElementType int struct SNode { ElementType Data; Stack Next; }; //get link stack length,the empty stack has a header, the default length is 0 int length(Stack ptrs) { Stack temp = ptrs; int len = 0; while (temp->Next) { temp = temp->Next; len++; } return len; } //make an empty linked Stack,generate an empty header(length is 1) Stack makeEmpty() { Stack ptrs; ptrs = (Stack)malloc(sizeof(struct SNode)); ptrs->Next = NULL; return ptrs; } //check the linklist is empty bool isEmpty(Stack ptrs) { if (length(ptrs) == 0) { return true; } else { return false; } } //push Stack push(ElementType value, Stack S) { Stack newLNode = (Stack)malloc(sizeof(struct SNode)); newLNode->Data = value; newLNode->Next = NULL; Stack ptrs = S; while (ptrs->Next) { ptrs = ptrs->Next; } ptrs->Next = newLNode; return S; } //pop ElementType pop(Stack S) { if (isEmpty(S)) { printf("the Stack has been empty."); return -1; } Stack ptrs = S; while (ptrs->Next->Next) { ptrs = ptrs->Next; } Stack temp = ptrs->Next; ElementType value = temp->Data; ptrs->Next = NULL; free(temp); return value; } //print Stack void printStack(Stack ptrs) { if (isEmpty(ptrs)) { return; } Stack temp = ptrs->Next; while (temp) { printf("%d ", temp->Data); temp = temp->Next; } printf("\n"); } int main() { Stack S = makeEmpty(); for (int i = 0; i < 2; i++) { ElementType value; scanf_s("%d", &value); S = push(value, S); } printStack(S); while (!isEmpty(S)) { printf("%d ", pop(S)); } return 0; }
队列,顾名思义就是像排队同样,先来排队的人先排到,队列具备先进先出后进后出的特性。一样能够经过数组或者链表实现,下面给出实现代码。dom
//implements by array #include<stdio.h> #include<stdbool.h> #include"malloc.h" #define ElementType int #define MAXSIZE 10 typedef struct QNode* Queue; struct QNode { ElementType Data[MAXSIZE]; int front; int rear; }; Queue makeempty() { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->front = 0; Q->rear = 0; return Q; } void QueueAdd(ElementType value, Queue ptrq) { if ((ptrq->rear + 1) % MAXSIZE == ptrq->front) { printf("The quque has been full."); return; } ptrq->rear = (++ptrq->rear) % MAXSIZE; ptrq->Data[ptrq->rear] = value; } ElementType QueueDelete(Queue ptrq) { if (ptrq->front == ptrq->rear) { printf("The queue has been empty."); return -1; } ptrq->front = (++ptrq->front) % MAXSIZE; return ptrq->Data[ptrq->front]; } int main(void) { Queue Q = makeempty(); for (int i = 1; i < 10;i++) { ElementType value; scanf_s("%d", &value); QueueAdd(value,Q); } QueueDelete(Q); QueueAdd(10, Q); return 0; }
//implements by linklist #include<stdio.h> #include<stdlib.h> #define ElementType int typedef struct QNode* Queue; struct QNode { ElementType Data; Queue Next; }; Queue makeEmpty() { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->Next = NULL; return Q; } void QueueAdd(ElementType value, Queue Q) { Queue temp = Q->Next; Queue newNode = (Queue)malloc(sizeof(struct QNode)); newNode->Data = value; newNode->Next = temp; Q->Next = newNode; } ElementType QueueDelete(Queue Q) { Queue ptrq = Q; if (!ptrq->Next) { printf("The queue has been empty."); return -1; } while (ptrq->Next->Next) { ptrq = ptrq->Next; } Queue temp = ptrq->Next; ptrq->Next = NULL; ElementType value = temp->Data; free(temp); return value; } int main(void) { Queue Q = makeEmpty(); for (int i = 1; i < 5; i++) { ElementType value; scanf_s("%d", &value); QueueAdd(value, Q); } QueueDelete(Q); QueueAdd(5, Q); return 0; }
本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。
函数接口定义:函数
List Merge( List L1, List L2 );测试
其中List结构定义以下:this
typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; /* 定义单链表类型 */
L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。
裁判测试程序样例:
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct Node *PtrToNode; struct Node { ElementType Data; PtrToNode Next; }; typedef PtrToNode List; List Read(); /* 细节在此不表 */ void Print( List L ); /* 细节在此不表;空链表将输出NULL */ List Merge( List L1, List L2 ); int main() { List L1, L2, L; L1 = Read(); L2 = Read(); L = Merge(L1, L2); Print(L); Print(L1); Print(L2); return 0; } /* 你的代码将被嵌在这里 */
输入样例:
3
1 3 5
5
2 4 6 8 10
输出样例:
1 2 3 4 5 6 8 10
NULL
NULL
代码:
#include <stdio.h> #include <stdlib.h> #include"malloc.h" typedef int ElementType; typedef struct Node* PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; List Read(); /* 细节在此不表 */ void Print(List L); /* 细节在此不表;空链表将输出NULL */ List Merge(List L1, List L2); int main() { List L1, L2, L; L1 = Read(); L2 = Read(); L = Merge(L1, L2); Print(L); Print(L1); Print(L2); return 0; } List Read() { //申请一块空间储存l,初始的最后一位是0 List L = (List)malloc(sizeof(struct Node)); L->Next = NULL; List ptrl = L; //要读多少个数? int num; scanf_s("%d", &num); //逐个读入,读入的同时增大最后一位的位置。 for (int i = 0; i < num;i++) { ElementType value; scanf_s("%d", &value); List newLNode = (List)malloc(sizeof(struct Node)); newLNode->Data = value; newLNode->Next = NULL; ptrl->Next = newLNode; ptrl = ptrl->Next; } return L; } void Print(List L) { int isfrist = 1; List ptrl = L->Next; if (ptrl == NULL) { printf("NULL\n"); return; } else { while (ptrl) { if (isfrist) { printf("%d", ptrl->Data); isfrist = 0; } else { printf(" %d", ptrl->Data); } ptrl = ptrl->Next; } printf("\n"); } return; } List Merge(List L1,List L2) { //存储合并后的链表 List L = (List)malloc(sizeof(struct Node)); //三个指针分别用于遍历l1和l2和L List ptrl1 = L1->Next, ptrl2 = L2->Next,ptrl = L; //两个链表都不空时,进行循环比较,其中任意一方空则退出 while (ptrl1 && ptrl2) { //ptrl1指向的数据比ptrl2时,将其 if (ptrl1->Data < ptrl2->Data) { ptrl->Next = ptrl1; ptrl1 = ptrl1->Next; } else { ptrl->Next = ptrl2; ptrl2 = ptrl2->Next; } ptrl = ptrl->Next; } //若是链表1空了,将如今未处理的链表2接到l末位,列表2空了同理..... if (ptrl1==NULL) { ptrl->Next = ptrl2; } if (ptrl2==NULL) { ptrl->Next = ptrl1; } //将l1和l2指向为null L1->Next = NULL; L2->Next = NULL; //将合并后的链表返回 return L; }
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
代码:
#include<stdio.h> #include<stdbool.h> #include "malloc.h" typedef struct Node* List; #define ElementType int struct Node { ElementType Coef; ElementType Degree; List Next; }; List Read() { //申请一块空间储存l,初始的最后一位是0 List L = (List)malloc(sizeof(struct Node)); L->Next = NULL; List ptrl = L; //要读多少个数? int num; scanf_s("%d", &num); //逐个读入,读入的同时增大最后一位的位置。 for (int i = 0; i < num; i++) { ElementType coef; ElementType degree; scanf_s("%d", &coef); scanf_s("%d", °ree); List newLNode = (List)malloc(sizeof(struct Node)); newLNode->Coef = coef; newLNode->Degree = degree; newLNode->Next = NULL; ptrl->Next = newLNode; ptrl = ptrl->Next; } return L; } //print List void printList(List ptrl) { if (!ptrl->Next) { printf("0 0\n"); return; } int isfrist = 1; List temp = ptrl->Next; while (temp) { if (isfrist) { printf("%d %d", temp->Coef, temp->Degree); isfrist = 0; } else { printf(" %d %d", temp->Coef, temp->Degree); } temp = temp->Next; } printf("\n"); } //按从大到小的排序插入 List insert(List newNode, List L) { List ptrl = L; //若是l是空的则直接插入 if (ptrl->Next == NULL) { ptrl->Next = newNode; } else { while (ptrl->Next && newNode->Degree < ptrl->Next->Degree) { ptrl = ptrl->Next; } if (ptrl->Next == NULL) { ptrl->Next = newNode; } //两个多项式的次方相同,合并他们。 else if (ptrl->Next->Degree == newNode->Degree) { //若是节点合并后系数为0,删除该节点 if (newNode->Coef + ptrl->Next->Coef == 0) { List temp = ptrl->Next; ptrl->Next = temp->Next; free(temp); free(newNode); } else { ptrl->Next->Coef += newNode->Coef; } } //ptrl所指向的下一个节点的次方小于新节点,将新结点插入在ptrl和它下一个节点之间。 else { List temp = ptrl->Next; ptrl->Next = newNode; newNode->Next = temp; } } return L; } List Polynomialmultiplication(List L1, List L2) { //存储合并后的链表 List L = (List)malloc(sizeof(struct Node)); L->Next = NULL; //三个指针分别用于遍历l1和l2 List ptrl1 = L1->Next, ptrl2 = L2->Next; //两个链表都不空时,进行乘法运算,其中任意一方空则退出 if (ptrl1 == NULL || ptrl2 == NULL) { return L; } //循环至两个列表都空 while (ptrl1) { while (ptrl2) { List newNode = (List)malloc(sizeof(struct Node)); newNode->Coef = ptrl1->Coef * ptrl2->Coef; newNode->Degree = ptrl1->Degree + ptrl2->Degree; newNode->Next = NULL; L = insert(newNode, L); ptrl2 = ptrl2->Next; } ptrl2 = L2->Next; ptrl1 = ptrl1->Next; } return L; } List Polynomialaddition(List L1, List L2) { //存储合并后的链表 List L = (List)malloc(sizeof(struct Node)); //三个指针分别用于遍历l1和l2和L List ptrl1 = L1->Next, ptrl2 = L2->Next, ptrl = L; //两个链表都不空时,进行乘法运算,其中任意一方空则退出 while (ptrl1 && ptrl2) { //创建一个新的节点。 List newNode = (List)malloc(sizeof(struct Node)); newNode->Next = NULL; //ptrl1指向的数据比ptrl2大时,将其复制添加到l末 if (ptrl1->Degree > ptrl2->Degree) { newNode->Coef = ptrl1->Coef; newNode->Degree = ptrl1->Degree; ptrl->Next = newNode; ptrl1 = ptrl1->Next; ptrl = ptrl->Next; } //ptrl2指向的数据比ptrl1大时,将其复制添加到l末 else if (ptrl1->Degree < ptrl2->Degree) { newNode->Coef = ptrl2->Coef; newNode->Degree = ptrl2->Degree; ptrl->Next = newNode; ptrl2 = ptrl2->Next; ptrl = ptrl->Next; } //ptrl2指向的数据和ptrl1同样大时,储存他们的和后添加到L else { //若是系数不为0的添加,不然将释放该节点。 ElementType newcoef = ptrl1->Coef + ptrl2->Coef; if (newcoef) { newNode->Coef = ptrl1->Coef + ptrl2->Coef; newNode->Degree = ptrl1->Degree; ptrl->Next = newNode; ptrl = ptrl->Next; } else { free(newNode); } ptrl1 = ptrl1->Next; ptrl2 = ptrl2->Next; } } //若是链表1空了,将如今未处理的链表2接到l末位,列表2空了同理..... if (ptrl1 == NULL) { ptrl->Next = ptrl2; } if (ptrl2 == NULL) { ptrl->Next = ptrl1; } //将合并后的链表返回 return L; } int main(void) { List L1, L2; L1 = Read(); L2 = Read(); List L4 = Polynomialmultiplication(L1, L2); printList(L4); List L3 = Polynomialaddition(L1, L2); printList(L3); return 0; }
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤\(10 ^5\)) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
\(Address\) \(Data\) \(Next\)
where \(Address\) is the position of the node, \(Data\) is an integer, and \(Next\) is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
代码:
#include<stdio.h> #include<stdlib.h> typedef struct Node* List; struct Node { int Address; int Data; int Next; List link; }; //获取链表长度,由于N只是输入节点而非有效节点 int length(List ptrl) { List temp = ptrl; int len = 0; while (temp->link) { temp = temp->link; len++; } return len; } //将对应地址的节点从链表删除,而且返回回来准备从新插入 List returnInValue(int value, List L) { List temp = L; while (temp->link) { if (temp->link->Address == value) { break; } temp = temp->link; } List key = temp->link; temp->link = key->link; key->link = NULL; return key; } //读取并排序 List Read(int firstAddress,int N,int K) { List L1 = (List)malloc(sizeof(struct Node)); L1->link = NULL; List ptrl = L1; //将节点存入链表L1 for(int i = 0;i < N;i++) { int Address, Data, Next; scanf_s("%d %d %d",&Address,&Data,&Next); List newnode = (List)malloc(sizeof(struct Node)); newnode->Address = Address; newnode->Data = Data; newnode->Next = Next; newnode->link = NULL; ptrl->link = newnode; ptrl = ptrl->link; } //根据节点中的地址和下一个排序,将排好序的存在L2(由于有可能有些节点是无效的) List L2 = (List)malloc(sizeof(struct Node)); L2->link = NULL; List ptrl2 = L2; int findaddress = firstAddress; while (findaddress!=-1) { List key = returnInValue(findaddress, L1); key->link = ptrl2->link; ptrl2->link = key; findaddress = key->Next; ptrl2 = ptrl2->link; } return L2; } //根据第几个来返回节点 List returnInIndex(int index, List L) { List temp = L; for (int i = 1; i < index; i++) { temp = temp->link; } List key = temp->link; temp->link = key->link; key->link = NULL; return key; } //反转链表而且将反转后的链表节点中的Next调整正常 List specialsort(List L,int N,int K) { //若是K=1,不用反转,反转后也同样 if (K == 1) { return L; } //创建新表头 List finalList = (List)malloc(sizeof(struct Node)); finalList->link = NULL; List ptrfl = finalList; //直到把L中全部的节点搬走后结束 int num = N - (N % K); int index = K; //先把须要反转的搬走 for (int i = 0; i < num; i++) { List node = returnInIndex(index--,L); ptrfl->link = node; ptrfl->Next = node->Address; ptrfl = ptrfl->link; if (index == 0) { index = K; } } //再将无需翻转的接到finalList,别忘了当前ptrfl指向的节点,Next的值尚未修改。 if (L->link) { ptrfl->Next = L->link->Address; ptrfl->link = L->link; } //将ptrfl指向最后一个节点,把他的next值改成-1。 while (ptrfl->link) { ptrfl = ptrfl->link; } ptrfl->Next = -1; return finalList; } void printList(List L) { List ptrl = L->link; while (ptrl) { printf("%05d %d ", ptrl->Address, ptrl->Data); if (ptrl->Next == -1) { printf("%d\n", ptrl->Next); } else { printf("%05d\n", ptrl->Next); } ptrl = ptrl->link; } } int main(void) { int firstAddress, N, K; scanf_s("%d %d %d", &firstAddress, &N, &K); //用于读取节点并按照格式排序 List readList = Read(firstAddress, N, K); //存储反转后的链表 List finalList = specialsort(readList,length(readList) ,K); //按照格式打印 printList(finalList); return 0; }
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input Specification:
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
Output Specification:
For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not.
Sample Input:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
Sample Output:
YES
NO
NO
YES
NO
代码:
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include "malloc.h" typedef struct SNode* Stack; #define MAXSIZE 1000 #define ElementType int struct SNode { ElementType Data[MAXSIZE]; int top; }; //make a empty stack Stack makeEmpty() { Stack S = (Stack)malloc(sizeof(struct SNode)); S->top = 0; return S; } //check is empty bool isEmpty(Stack ptrs) { if (ptrs->top == 0) { return true; } return false; } //check is full bool isFull(Stack ptrs,int Max) { if (ptrs->top == Max+1) { return true; } return false; } //push element void push(ElementType value, Stack ptrs) { ptrs->Data[ptrs->top++] = value; } //pop ElementType pop(Stack ptrs) { ptrs->top = ptrs->top - 1; return ptrs->Data[ptrs->top]; } int main(void) { int M, N, K; scanf_s("%d %d %d", &M, &N, &K); //读取K次 for (int i = 0; i < K; i++) { //默认是合法,检测到异常再定义为不合法 bool isright = true; //建一个空堆栈 Stack S = makeEmpty(); //将出栈顺序保存 int array[1001]; for (int i = 0; i < N; i++) { scanf_s("%d", &array[i]); } //index对应array下标,直到遍历完成且中途没有发生不合理的事说明合法 int index = 0; int num = 0;//num为压栈的次数 while (index != N) { //若是下标所指的值大于目前压栈的次数,压栈 if (num < array[index]) { while (num < array[index]) { push(++num, S); //每次压过判断是否满了(大于N) if (isFull(S,M)) { isright = false; goto LOOP_VAL; } } //抛出并检查是否同样 pop(S); } //若是下标所指的值小于目前压栈的次数,出栈 else { //若是出栈的节点不为当前下标所指的值,说明有问题 int temp = pop(S); if (temp != array[index]) { isright = false; break; } } index++; } LOOP_VAL: //标号 if (isright) { printf("YES\n"); } else { printf("NO\n"); } } }