【MOOC-浙江大学-陈越、何钦铭-数据结构】线性结构-线性表、堆栈与队列(第二周的笔记和编程作业)
文章目录
- 1、02-线性结构1 两个有序链表序列的合并 (15分)
- 2、02-线性结构2 一元多项式的乘法与加法运算 (20分)
- 3、02-线性结构3 Reversing Linked List (25分)
- 4、02-线性结构3 Reversing Linked List (25分)
〇、前言
这两周开始跟着【MOOC-浙江大学-陈越、何钦铭-数据结构】进行数据结构与算法的学习,特此记录复习一下,虽然记不住,但是一直记一直记一直记,成为复读机就好了。
一、线性表
线性表(Linear List):由同类型数据元素构成有序序列的线性结构
- 表中元素个数称为 线性表的长度
- 线性表没有元素时,称为 空表
- 表起始位置称 表头,表结束位置称 表尾
1、List MakeEmpty():初始化一个空线性表L;
2、ElementType FindKth( int K, List L ):根据位序K,返回相应元素 ;
3、int Find( ElementType X, List L ):在线性表L中查找X的第一次出现位置;
4、void Insert( ElementType X, int i, List L):在位序i前插入一个新元素X;
5、void Delete( int i, List L ):删除指定位序i的元素;
6、int Length( List L ):返回线性表L的长度n。
1、线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各元素。
typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; }; /* 初始化 */ List MakeEmpty() { List L; L = (List)malloc(sizeof(struct LNode)); L->Last = -1; return L; } /* 查找 */ #define ERROR -1 Position Find( List L, ElementType X ) { Position i = 0; while( i <= L->Last && L->Data[i]!= X ) i++; if ( i > L->Last ) return ERROR; /* 如果没找到,返回错误信息 */ else return i; /* 找到后返回的是存储位置 */ } /* 插入 */ /*注意:在插入位置参数P上与课程视频有所不同, 课程视频中i是序列位序(从1开始),这里P是存储下标位置(从0开始),两者差1*/ bool Insert( List L, ElementType X, Position P ) { /* 在L的指定位置P前插入一个新元素X */ Position i; if ( L->Last == MAXSIZE-1) { /* 表空间已满,不能插入 */ printf("表满"); return false; } if ( P<0 || P>L->Last+1 ) { /* 检查插入位置的合法性 */ printf("位置不合法"); return false; } for( i=L->Last; i>=P; i-- ) L->Data[i+1] = L->Data[i]; /* 将位置P及以后的元素顺序向后移动 */ L->Data= X; /* 新元素插入 */ L->Last++; /* Last仍指向最后元素 */ return true; } /* 删除 */ /*注意:在删除位置参数P上与课程视频有所不同, 课程视频中i是序列位序(从1开始),这里P是存储下标位置(从0开始),两者差1*/ bool Delete( List L, Position P ) { /* 从L中删除指定位置P的元素 */ Position i; if( P<0 || P>L->Last ) { /* 检查空表及删除位置的合法性 */ printf("位置%d不存在元素", P ); return false; } for( i=P+1; i<=L->Last; i++ ) L->Data[i-1] = L->Data[i]; /* 将位置P+1及以后的元素顺序向前移动 */ L->Last--; /* Last仍指向最后元素 */ return true; }
2、线性表的链式存储实现
[p]不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。
typedef struct LNode *PtrToLNode; struct LNode { ElementType Data; PtrToLNode Next; }; typedef PtrToLNode Position; typedef PtrToLNode List; /* 查找 */ #define ERROR NULL Position Find( List L, ElementType X ) { Position p = L; /* p指向L的第1个结点 */ while ( p && p->Data!=X ) p = p->Next; /* 下列语句可以用 return p; 替换 */ if ( p ) return p; else return ERROR; } /* 带头结点的插入 */ /*注意:在插入位置参数P上与课程视频有所不同, 课程视频中i是序列位序(从1开始),这里P是链表结点指针,在P之前插入新结点 */ bool Insert( List L, ElementType X, Position P ) { /* 这里默认L有头结点 */ Position tmp, pre; /* 查找P的前一个结点 */ for ( pre=L; pre&&pre->Next!=P; pre=pre->Next ) ; if ( pre==NULL ) { /* P所指的结点不在L中 */ printf("插入位置参数错误\n"); return false; } else { /* 找到了P的前一个结点pre */ /* 在P前插入新结点 */ tmp = (Position)malloc(sizeof(struct LNode)); /* 申请、填装结点 */ tmp->Data = X; tmp->Next = P; pre->Next = tmp; return true; } } /* 带头结点的删除 */ /*注意:在删除位置参数P上与课程视频有所不同, 课程视频中i是序列位序(从1开始),这里P是拟删除结点指针 */ bool Delete( List L, Position P ) { /* 这里默认L有头结点 */ Position tmp, pre; /* 查找P的前一个结点 */ for ( pre=L; pre&&pre->Next!=P; pre=pre->Next ) ; if ( pre==NULL || P==NULL) { /* P所指的结点不在L中 */ printf("删除位置参数错误\n"); return false; } else { /* 找到了P的前一个结点pre */ /* 将P位置的结点删除 */ pre->Next = P->Next; free(P); return true; } }
二、堆栈
后入先出:Last In First Out(LIFO)
1、Stack CreateStack( int MaxSize ): 生成空堆栈,其最大长度为MaxSize;
2、int IsFull( Stack S, int MaxSize ):判断堆栈S是否已满;
3、void Push( Stack S, ElementType item ):将元素item压入堆栈;
4、int IsEmpty ( Stack S ):判断堆栈S是否为空;
5、ElementType Pop( Stack S ):删除并返回栈顶元素;
1、堆栈的定义与操作,顺序存储实现
typedef int Position; struct SNode { ElementType *Data; /* 存储元素的数组 */ Position Top; /* 栈顶指针 */ int MaxSize; /* 堆栈最大容量 */ }; typedef struct SNode *Stack; Stack CreateStack( int MaxSize ) { Stack S = (Stack)malloc(sizeof(struct SNode)); S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); S->Top = -1; S->MaxSize = MaxSize; return S; } bool IsFull( Stack S ) { return (S->Top == S->MaxSize-1); } bool Push( Stack S, ElementType X ) { if ( IsFull(S) ) { printf("堆栈满"); return false; } else { S->Data[++(S->Top)] = X; return true; } } bool IsEmpty( Stack S ) { return (S->Top == -1); } ElementType Pop( Stack S ) { if ( IsEmpty(S) ) { printf("堆栈空"); return ERROR; /* ERROR是ElementType的特殊值,标志错误 */ } else return ( S->Data[(S->Top)--] ); }
2、堆栈的定义与操作,链式存储实现
typedef struct SNode *PtrToSNode; struct SNode { ElementType Data; PtrToSNode Next; }; typedef PtrToSNode Stack; Stack CreateStack( ) { /* 构建一个堆栈的头结点,返回该结点指针 */ Stack S; S = (Stack)malloc(sizeof(struct SNode)); S->Next = NULL; return S; } bool IsEmpty ( Stack S ) { /* 判断堆栈S是否为空,若是返回true;否则返回false */ return ( S->Next == NULL ); } bool Push( Stack S, ElementType X ) { /* 将元素X压入堆栈S */ PtrToSNode TmpCell; TmpCell = (PtrToSNode)malloc(sizeof(struct SNode)); TmpCell->Data = X; TmpCell->Next = S->Next; S->Next = TmpCell; return true; } ElementType Pop( Stack S ) { /* 删除并返回堆栈S的栈顶元素 */ PtrToSNode FirstCell; ElementType TopElem; if( IsEmpty(S) ) { printf("堆栈空"); return ERROR; } else { FirstCell = S->Next; TopElem = FirstCell->Data; S->Next = FirstCell->Next; free(FirstCell); return TopElem; } }
三、队列
先来先服务,先进先出:FIFO
1、Queue CreatQueue( int MaxSize ):生成长度为MaxSize的空队列;
2、int IsFullQ( Queue Q, int MaxSize ):判断队列Q是否已满;
3、void AddQ( Queue Q, ElementType item ): 将数据元素item插入队列Q中;
4、int IsEmptyQ( Queue Q ): 判断队列Q是否为空;
5、ElementType DeleteQ( Queue Q ):将队头数据元素从队列中删除并返回。
1、队列的定义与操作,顺序存储实现
typedef int Position; struct QNode { ElementType *Data; /* 存储元素的数组 */ Position Front, Rear; /* 队列的头、尾指针 */ int MaxSize; /* 队列最大容量 */ }; typedef struct QNode *Queue; Queue CreateQueue( int MaxSize ) { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); Q->Front = Q->Rear = 0; Q->MaxSize = MaxSize; return Q; } bool IsFull( Queue Q ) { return ((Q->Rear+1)%Q->MaxSize == Q->Front); } bool AddQ( Queue Q, ElementType X ) { if ( IsFull(Q) ) { printf("队列满"); return false; } else { Q->Rear = (Q->Rear+1)%Q->MaxSize; Q->Data[Q->Rear] = X; return true; } } bool IsEmpty( Queue Q ) { return (Q->Front == Q->Rear); } ElementType DeleteQ( Queue Q ) { if ( IsEmpty(Q) ) { printf("队列空"); return ERROR; } else { Q->Front =(Q->Front+1)%Q->MaxSize; return Q->Data[Q->Front]; } }
2、队列的定义与操作,链式存储实现
typedef struct Node *PtrToNode; struct Node { /* 队列中的结点 */ ElementType Data; PtrToNode Next; }; typedef PtrToNode Position; struct QNode { Position Front, Rear; /* 队列的头、尾指针 */ int MaxSize; /* 队列最大容量 */ }; typedef struct QNode *Queue; bool IsEmpty( Queue Q ) { return ( Q->Front == NULL); } ElementType DeleteQ( Queue Q ) { Position FrontCell; ElementType FrontElem; if ( IsEmpty(Q) ) { printf("队列空"); return ERROR; } else { FrontCell = Q->Front; if ( Q->Front == Q->Rear ) /* 若队列只有一个元素 */ Q->Front = Q->Rear = NULL; /* 删除后队列置为空 */ else Q->Front = Q->Front->Next; FrontElem = FrontCell->Data; free( FrontCell ); /* 释放被删除结点空间 */ return FrontElem; } }
四、一元多项式的 加法与乘法运算
题意理解:
实现在后面的第二题!
五、课后题
1、02-线性结构1 两个有序链表序列的合并 (15分)
#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
List Merge( List L1, List L2 ){ List L,p1,p2,p3; L=(List)malloc(sizeof(PtrToNode)); p1=L1->Next; p2=L2->Next; p3=L; while(p1&&p2){ if(p1->Data<p2->Data){ p3->Next=p1; p3=p3->Next; p1=p1->Next; } else{ p3->Next=p2; p3=p3->Next; p2=p2->Next; } } if(p1==NULL){ p3->Next=p2; } else if(p2==NULL){ p3->Next=p1; } L1->Next=NULL; L2->Next=NULL; return L; }
2、02-线性结构2 一元多项式的乘法与加法运算 (20分)
对应上面的求解。
输入样例:
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<stdlib.h> typedef struct PolyNode *Polynomial; struct PolyNode{ int coef; int expon; Polynomial link; }; void Attach(int c,int e,Polynomial *pRear){ Polynomial P; P=(Polynomial)malloc(sizeof(struct PolyNode)); P->coef=c; P->expon=e; P->link=NULL; (*pRear)->link=P; *pRear=P; } Polynomial ReadPoly(){ Polynomial P,Rear,t; int c,e,N; scanf("%d",&N); P=(Polynomial)malloc(sizeof(struct PolyNode)); P->link=NULL; Rear=P; while(N--){ scanf("%d %d",&c,&e); Attach(c,e,&Rear); } t=P; P=P->link; free(t); return P; } Polynomial Mult(Polynomial P1, Polynomial P2){ Polynomial t1,t2,P,Rear,t; int e,c; if(!P1||!P2) return NULL; t1 = P1; t2 = P2; P = (Polynomial)malloc(sizeof(struct PolyNode)); P->link = NULL; Rear=P; while(t2){ Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear); t2 = t2->link; } t1 = t1->link; while(t1){ Rear = P; t2 = P2; while(t2){ c = t1->coef*t2->coef; e = t1->expon+t2->expon; while(Rear->link&&Rear->link->expon>e) Rear=Rear->link; if(Rear->link &&Rear->link->expon==e){ if(Rear->link->coef+c) Rear->link->coef+=c; else{ t = Rear->link; Rear->link = t->link; free(t); } } else{ t = (Polynomial)malloc(sizeof(struct PolyNode)); t->coef = c; t->expon=e; t->link = Rear->link; Rear->link =t; Rear = Rear->link; } t2 = t2->link; } t1 = t1->link; } t = P; P = P->link; free(t); return P; } Polynomial Add(Polynomial P1, Polynomial P2){ Polynomial t1,t2,P,Rear,t; int e,c; if(!P1&&!P2) return NULL; t1 = P1; t2 = P2; P=(Polynomial)malloc(sizeof(struct PolyNode)); Rear = P; while(t1&&t2){ if(t1->expon==t2->expon){ if(t1->coef!=-(t2->coef)) Attach(t1->coef+t2->coef, t1->expon, &Rear); t1 = t1->link; t2 = t2->link; } else if(t1->expon>t2->expon){ Attach(t1->coef, t1->expon, &Rear); t1 = t1->link; } else { Attach(t2->coef, t2->expon, &Rear); t2 = t2->link; } } Rear->link = t1 ? t1 : t2; t = P; P = P->link; free(t); return P; } void PrintPoly(Polynomial P){ int flag=0; if(!P){ printf("0 0\n"); return; } while(P){ if(!flag) flag=1; else printf(" "); printf("%d %d",P->coef,P->expon); P=P->link; } printf("\n"); } int main(){ Polynomial P1,P2,PP,PS; P1=ReadPoly(); P2=ReadPoly(); PP=Mult(P1,P2); PrintPoly(PP); PS=Add(P1,P2); PrintPoly(PS); return 0; }
3、02-线性结构3 Reversing Linked List (25分)
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> #define MaxSize 100005 int main(){ int Data[MaxSize]; int Next[MaxSize]; int List[MaxSize]; int FirstAdd,N,K; scanf("%d %d %d",&FirstAdd,&N,&K); int i,j; for(i=0;i<N;i++){ int tAdd,tData,tNext; scanf("%d %d %d",&tAdd,&tData,&tNext); Data[tAdd]=tData; Next[tAdd]=tNext; } int sum=0; while(FirstAdd!=-1){ List[sum++]=FirstAdd; FirstAdd=Next[FirstAdd]; } for(i=0;i<sum-sum%K;i+=K){ for(j=0;j<K/2;j++){ int t=List[i+j]; List[i+j]=List[i+K-j-1]; List[i+K-j-1]=t; } } for(i=0;i<sum-1;i++){ printf("%05d %d %05d\n",List[i],Data[List[i]],List[i+1]); } printf("%05d %d -1\n",List[i],Data[List[sum-1]]); return 0; }
4、02-线性结构3 Reversing Linked List (25分)
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> typedef struct SNode *Stack; struct SNode{ int data[1010]; int top; }; void push(Stack ptrl,int a); void pop(Stack ptrl); int main(){ Stack ptrl; ptrl=(Stack)malloc(sizeof(struct SNode)); // ptrl->top=-1; int m,n,k,i,j; scanf("%d %d %d",&m,&n,&k); int b[1010]; while(k--){ ptrl->top=-1; j=0; for(i=0;i<n;i++){ scanf("%d",&b[i]); } for(i=1;i<=n;i++){ push(ptrl,i); if(ptrl->top >= m){ break; } while(ptrl->top!=-1&&ptrl->data[ptrl->top]==b[j]){ j++; pop(ptrl); } } if (ptrl->top == -1) { printf("YES\n"); } else { printf("NO\n"); } } } void push(Stack ptrl,int a){ ptrl->data[++(ptrl->top)]=a; } void pop(Stack ptrl){ ptrl->top--; }
总结
简单总结下这周的学习内容,正式开始接触了数据结构与算法,线性表,堆栈,队列等等,感觉自己真的是太菜,好多题都不会,只能参考别人的,,,还是得手撕代码!!!都背一背!!!
- 点赞 1
- 收藏
- 分享
- 文章举报
- 【MOOC-浙江大学-陈越、何钦铭-数据结构】数据结构与算法的基本概念(第一周的笔记和编程作业)
- 中国大学MOOC-陈越、何钦铭-数据结构-2019春 02-线性结构4 Pop Sequence
- 网易云课堂-陈越、何钦铭-数据结构-2016春,02-线性结构1 一元多项式的乘法与加法运算,学习笔记
- 02-线性结构1 两个有序链表序列的合并——中国大学MOOC-陈越、何钦铭-数据结构-2017秋
- 中国大学MOOC-陈越、何钦铭-数据结构-2015秋02-线性结构1题解
- 陈越、何钦铭《数据结构》第二讲线性结构 笔记
- 数据结构 学习笔记(三):线性结构:堆栈,队列,表达式求值,多项式加法运算
- 02-线性结构2 一元多项式的乘法与加法运算-中国大学MOOC-陈越、何钦铭-数据结构-2017秋
- 中国大学MOOC-陈越、何钦铭-数据结构-2017秋 02-线性结构4 Pop Sequence
- PTA中国大学MOOC-陈越、何钦铭-数据结构-2017春课后作业03树1 树的同构
- 【陈越 数据结构】第二讲 线性结构2-堆栈&队列
- 数据结构(陈越)PAT练习题 第二周:线性结构
- 【郝斌数据结构自学笔记】57-59_递归8 _ 汉诺塔_1线性结构总复习 2线性结构和非线性结构关系 3栈队列链表数组之间的关系【重点】
- 数据结构之线性结构---线性表,堆栈,队列
- 中国大学MOOC-陈越、何钦铭-数据结构-笔记
- 中国大学MOOC-陈越、何钦铭-数据结构 Insertion or Heap Sort
- 网易云课堂-陈越、何钦铭-数据结构-2016春,学习笔记,广义表和多重链表
- 中国大学MOOC-陈越、何钦铭-数据结构 列出连通集
- 数据结构编程笔记五:第二章 线性表 静态链表的实现
- [数据结构]线性结构——队列