线性表
课程给出代码
C语言描述顺序表操作
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[P] = 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;
}
C语言描述链表
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;
}
}
C语言描述顺序栈
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)--] );
}
C语言描述链栈
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;
}
}
C语言描述顺序队列
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];
}
}
C语言描述链队列
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;
}
}
02-线性结构1 两个有序链表序列的合并 (15 分)
List Merge( List L1, List L2 )//合并函数本题需要写的函数
{
List pa,pb,pc,L;
L = (List)malloc(sizeof(struct Node));
pa=L1->Next;
pb=L2->Next;
pc = L; //pc用来存储中间值,L用来存表头位置
while(pa && pb)
{
if(pa->Data <= pb->Data)
{
pc->Next = pa;
pc = pa;
pa = pa->Next;
}
else
{
pc->Next = pb;
pc = pb;
pb = pb->Next;
}
}
pc->Next = pa ? pa : pb;//接上未空表的数据
L1->Next = NULL;
L2->Next = NULL;
return L;
}
02-线性结构2 一元多项式的乘法与加法运算 (20 分)
题目:
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 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 temp;
temp=(Polynomial)malloc(sizeof(Polynomial));
temp->coef=c;
temp->expon=e;
temp->link=NULL;
(*pRear)->link=temp;
*pRear=temp; //此处要加*,因为引入的是p的地址
}
Polynomial ReadPoly(){
int n,c,e;
Polynomial temp,p;
p=(Polynomial)malloc(sizeof(Polynomial));
p->link=NULL;
temp=p;
scanf("%d",&n);
while(n--){
scanf("%d %d",&c,&e);
Attach(c,e,&temp);
}
return p->link;//返回的不带表头的链表
}
Polynomial Add(Polynomial p1,Polynomial p2)
{
Polynomial p,temp,p0;
p=(Polynomial)malloc(sizeof(Polynomial));
p->link=NULL;
temp=p;
while(p1&&p2){
if(p1->expon>p2->expon){
Attach(p1->coef,p1->expon,&p);
p1=p1->link;
}
else if(p1->expon<p2->expon){
Attach(p2->coef,p2->expon,&p);
p2=p2->link;
}
else if(p1->coef+p2->coef==0){
p1=p1->link;
p2=p2->link;
}
else{
Attach(p1->coef+p2->coef,p1->expon,&p);
p1=p1->link;
p2=p2->link;
}
}
while(p1) {Attach(p1->coef,p1->expon,&p); p1=p1->link;}
while(p2) {Attach(p2->coef,p2->expon,&p); p2=p2->link;}//后接剩下的
p0=temp; temp=temp->link; free(p0);//去掉临时的表头,输出temp—>link也成
return temp;
}
Polynomial Mult(Polynomial p1,Polynomial p2)
{
Polynomial p,temp,t1,t2,temp1,t;
t1=p1; t2=p2;
p=(Polynomial)malloc(sizeof(struct PolyNode));
p->link=NULL;
temp=p;
if(!t1||!t2)
return NULL;
while(t2) {//表一的第一项与表二所有项相乘
Attach((t1->coef)*(t2->coef),(t1->expon)+(t2->expon),&temp);
t2=t2->link;
}
t1=t1->link;
while(t1)//计算剩下的相乘项并插入到之前的数据中
{
t2=p2;//回到表二的表头准备与表一的下一项相乘
while(t2)
{
temp=p;//重新回到结果表的表头
while((temp->link)&&((t1->expon)+(t2->expon)<(temp->link)->expon))
temp=temp->link;
if ((temp->link)&&((t1->expon)+(t2->expon)==temp->link->expon))
{
if((t1->coef)*(t2->coef)+temp->link->coef==0){
temp1=temp->link;
temp->link=temp1->link;
free(temp1);
}//这种情况是系数为零了因此要去掉这一项
else{
temp->link->coef+=(t1->coef)*(t2->coef);
}
}
else{//不等只能大于则在前面插入这项
t=(Polynomial)malloc(sizeof(struct PolyNode));
t->coef=t1->coef*t2->coef;
t->expon=t1->expon+t2->expon;
t->link=temp->link;
temp->link=t;
temp=temp->link;
}
t2=t2->link;
}
t1=t1->link;//提出表一的下一项准备相乘
}
temp=p; p=p->link; free(temp);//去掉临时表头
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;
}
02-线性结构3 Reversing Linked List (25 分)
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.
注意是每隔K个元素翻转一次,不足K个元素则按原序输出。
题目给的测试例子是每个节点都有用到,而测试点中有些节点是没有用到的,所以要先找到在同一条链表的节点。
#include <iostream>
using namespace std;
typedef struct Node *N;
struct Node {
int data;
int next;
}L[100000];
void Read(int n){
int i,p;
for (i = 0; i < n; i++) {
cin >> p;
cin >> L[p].data >> L[p].next;
}
}
int Search(int pin,int K) {//查找第K个值即确定翻转范围
int i = K-1;
while(i-- && pin!=-1){
pin = L[pin].next;
}
return pin;
}
void Done(int* pin, int *plast) {
int pp = L[*plast].next;
int p = *pin;
int pn = L[p].next;
while (1) {
L[p].next = pp;
pp = p;
if (pp == *plast) {
break;
}
p = pn;
pn = L[pn].next;
}//前面改了next的值使pin到plast的顺序翻转为了让这部分重新接入到序列中
int tmp = *pin;
*pin = *plast;
*plast = tmp;//这三行完成了首尾互换
}
void Reverse(int *p,int K){
int p_K;//K翻转时对应的值(第K值)
while (*p != -1) {
p_K = Search(*p,K);
if (p_K == -1)//剩余的值不够K个则剩下的值不翻转
break;
Done(p, &p_K);//进行翻转
p = &L[p_K].next;//每K个值一循环
}
}
void Print(int front){
while (1) {
printf("%05d %d ", front, L[front].data);
front = L[front].next;
if (front == -1) {
printf("-1\n");
break;
}
printf("%05d\n", front);
}
}
int main(){
int front, n, K;//记录头结点地址,节点数,翻转因子
cin >> front>> n >> K;
Read(n);
Reverse(&front,K);
Print(front);
return 0;
}
02-线性结构4 Pop Sequence (25 分)
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.
#include<iostream>
using namespace std;
int stack[1000];//建立一个栈
int main(){
int m, n, t;
cin >> m >> n >> t;
while (t--){
int num, top = 0, flag = 1, now = 1;//待比较的出栈元素;栈顶元素;判断标志;表示当前的值
for (int i = 0; i < n; i++){//遍历每一个数
cin >> num;
while ((top == 0 || num != stack[top]) && flag){//栈为空或者待出栈元素与栈顶元素不相等
stack[++top] = now;
if (top > m){//栈已超
flag = 0;
break;
}
now++;
}//这个while只是计算一个数有没有可能被push出一共有n个数
if (num == stack[top] && flag && top >= 1)//栈不为空且待出栈元素与栈顶元素相等则出栈
top--;
}
if (flag)
printf("YES\n");
else
printf("NO\n");
}
}