线性结构

线性表及其实现

线性表是由同类型数据元素构成的有序序列的线性结构。线性表的基本操作:插入,删除,查找。线性表中可以没有元素时,称为空表。
线性表可以用来表示多项式的加减乘等。
线性表的实现方式有两种,一种线性表的顺序存储实现,一种是线性表的链式存储实现。
线性表的顺序存储实现

List MakeEmpty()
{
    List L;
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
    return L;
}

查找:查找有两种,一种是按照序号查找,一种是按值查找。

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;  
}

插入:先检查是否能插入,线性表是否已满

bool Insert( List L, ElementType X, Position P ) 
{ 
    Position i;
 
    if ( L->Last == MAXSIZE-1) 
    {
        printf("线性表已满\n"); 
        return false; 
    }  
    if ( P<0 || P>L->Last+1 ) 
    { 
        printf("ERROR");
        return false; 
    } 
    for( i=L->Last; i>=P; i-- )
        L->Data[i+1] = L->Data[i]; 
    L->Data[P] = X;  
    L->Last++;      
    return true; 
} 

删除:删除要看线性表是否为空,为空就出现错误了。

bool Delete( List L, Position P )
{
    Position i;
    if( P<0 || P>L->Last ) 
    { 
        printf("ERROR\n"); 
        return false; 
    }
    for( i=P+1; i<=L->Last; i++ )
        L->Data[i-1] = L->Data[i]; 
    L->Last--; 
    return true;   
}

线性表的链式存储结构实现

typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};

查找:

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;
}

插入:先构造一个新结点,再找到要插入位置i的前一个位置,这个结点指向新结点,然后新结点再指向下一个结点。

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;
    }
}

删除:先找到链表的第i-1个结点,这个结点指向i+1个结点,就完成删除操作了。

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;
    }
}

广义表:就是比较复杂的链表。

Typedef struct GNode *GList;
struct GNode{
	int Tag;
	union{
			ElmentType Data;
			GList SubList;
			}URegion;
			GList Next;
	};

多重链表:链表中的结点可能同时属于多个链,一个结点有多个指针域。
例:矩阵既可以用二维数组表示,但当数据比较稀疏时,会造成浪费,所以可以用十字链表来表示矩阵。每个结点有两个指针域,把同行同列的数据串起来,一个行指针(右指针)一个列指针(左指针)。用一个标识域来区分是否为头结点。

堆栈

简单计算机:一般我们使用中缀表达式表示,后缀表达式就可以用堆栈的方式算出来。
用两个栈来,一个栈来装运算数,一个栈来装运算符,当要装的运算符的优先级比栈顶的优先级更小时,全部出栈,用来运算,左括号放入运算符后,优先级变小。
堆栈:具有一定操作的线性表。操作有插入(入栈),删除(出栈),后入先出。
栈的顺序存储实现:
初始化:

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);
}

push操作:如果栈满就出现错误

bool Push( Stack S, ElementType X )
{
    if ( IsFull(S) ) {
        printf("堆栈满");
        return false;
    }
    else {
        S->Data[++(S->Top)] = X;
        return true;
    }
}

pop操作:栈不能为空

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)--] );
}

栈的链式存储实现:
初始化:

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;
}

push操作:

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;
}

pop操作:

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;
    }
}

队列

队列时具有一定操作约束的线性表,队列的特点是先进先出。队列的基本操作有:插入,删除。
队列的顺序存储实现:
初始化:

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;
    }
}

删除:

ElementType DeleteQ( Queue Q )
{
    if ( IsEmpty(Q) ) { 
        printf("队列空");
        return ERROR;
    }
    else  {
        Q->Front =(Q->Front+1)%Q->MaxSize;
        return  Q->Data[Q->Front];
    }
}

队列的链式存储实现:
初始化:

typedef struct Node *PtrToNode;
struct Node { /* 队列中的结点 */
    ElementType Data;
    PtrToNode Next;
};
typedef PtrToNode Position;

删除:

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;
    }
}

多项式加法运算

算法思路:
两个指针指向两个多项式,当他们的指数相同时,系数相加,如果系数不为零,指向下一项。

#include<stdio.h>
#include<stdlib.h>

typedef struct PolyNode{
	int coef;
	int expon;
	struct PolyNode *next;
} *Polynomial;

Polynomial InitPolynomial();
void TraverseList(Polynomial l);
void CreatePolynomial(Polynomial l);
Polynomial PolyAdd(Polynomial p1, Polynomial p2);
Polynomial attach(int coef, int expon, Polynomial p);//

void main()
{
	Polynomial p1, p2, p;

	p1 = InitPolynomial();
	CreatePolynomial(p1);
	p2 = InitPolynomial();
	CreatePolynomial(p2);
	//TraverseList(p1);
	//TraverseList(p2);

	p = PolyAdd(p1, p2);
	p = p->next;
	TraverseList(p);
}

Polynomial InitPolynomial()
{
	Polynomial p;
	p = (Polynomial)malloc(sizeof(PolyNode));

	if (!p)
	{
		printf("fail");
		exit(1);
	}
	p->next = NULL;
	return p;
}

//遍历函数 
void TraverseList(Polynomial l)
{
	Polynomial r = l;
	while (l)
	{
		printf("系数:%d,指数:%d  ", l->coef, l->expon);
		l = l->next;
	}
	printf("\n");
}

void CreatePolynomial(Polynomial l)
{
	int i, n;
	Polynomial p, r = l;

	scanf_s("%d", &n);

	scanf_s("%d,%d", &l->coef, &l->expon);
	for (i = 1; i < n; i++)
	{
		p = (Polynomial)malloc(sizeof(PolyNode));
		scanf_s("%d,%d", &p->coef, &p->expon);
		r->next = p;
		r = p;
	}
	r->next = NULL;
}

Polynomial PolyAdd(Polynomial p1, Polynomial p2)
{
	int coef;
	Polynomial r, p;
	p = (Polynomial)malloc(sizeof(PolyNode));
	p->next = NULL;
	r = p;

	while (p1 && p2)
	{
		if (p1->expon == p2->expon)
		{
			coef = p1->coef + p2->coef;
			if (coef)
				p = attach(coef, p1->expon, p);
			p1 = p1->next;
			p2 = p2->next;
		}
		else if (p1->expon > p2->expon)
		{
			p = attach(p1->coef, p1->expon, p);
			p1 = p1->next;
		}
		else
		{
			p = attach(p2->coef, p2->expon, p);
			p2 = p2->next;
		}
	}
	
	for (; p1; p1 = p1->next) p = attach(p1->coef, p1->expon, p);
	for (; p2; p2 = p2->next) p = attach(p2->coef, p2->expon, p);
	return r;
}

Polynomial attach(int coef, int expon, Polynomial p)
{
	Polynomial r;

	r = (Polynomial)malloc(sizeof(PolyNode));
	r->coef = coef;
	r->expon = expon;
	r->next = p->next;
	p->next = r;
	p = r;
	return p;
}

一元多项式的加法与乘法运算

多项式表示有两种方式,一种数组,一种链表。用数组表示变成简单,容易操作。但用链表动态性更强。
用数组表示:

#include<stdio.h>
int main()
{
    int n,m;
    scanf("%d",&n);
    int a[10001]={0},b[10001]={0},c[10001]={0},d[10001]={0};
    int i,j;
    for(i=0;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        a[y]=x;
    }
    scanf("%d",&m);
    for(i=0;i<m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        b[y]=x;
    }
    for(i=0;i<=1000;i++)
    {
        for(j=0;j<=1000;j++)
            c[i+j]+=a[i]*b[j];
    }
    int flag=0;
    for(i=2000;i>=0;i--)
    {
        if(c[i]!=0)
        {
            if(flag)
                printf(" ");
            flag=1;
            printf("%d %d",c[i],i);
        }
    }
    if(!flag)
        printf("0 0");
    printf("\n");
    for(i=0;i<=1000;i++)
    {
        for(j=0;j<=1000;j++)
            d[i+j]=a[i]+b[i];
    }
    int mark=0;
    for(i=1000;i>=0;i--)
    {
        if(d[i]!=0)
        {
            if(mark)
                printf(" ");
            mark=1;
            printf("%d %d",d[i],i);
        }
    }
    if(!mark)
        printf("0 0");
    printf("\n");
    return 0;
}

用链表表示:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct Polynode
{
	int coef;
	int exp;
	struct Polynode *next;
}Polynode, *Polylist;
 
// 初始化
bool InitPoly(Polylist *Poly)
{
	*Poly = (Polylist)malloc(sizeof(Polynode));  
	if (!(*Poly))  
		return false;
	(*Poly)->next = NULL;
	return true;
}
 
void PolyCreate(Polylist head, int n)
{
	Polynode *rear, *s; 
	int c, e;
	rear = head;
	for (int i = 0; i < n; i++)
	{
		scanf("%d %d", &c, &e);
		s = (Polynode*)malloc(sizeof(Polynode));
		s->coef = c;
		s->exp = e;
		rear->next = s;  
		rear = s;        
	}
	rear->next = NULL;  
	
}
 
void Polyadd(Polylist polya, Polylist polyb)
{
 
	Polynode *p, *q, *pre, *temp;
	int sum;
	p = polya->next; 
	q = polyb->next; /
	pre = polya;     // pre表示和多项式的尾节点,初始与polya相同
	while (p != NULL && q != NULL)
	{
		if (p->exp > q->exp)  // a的结点加入和多项式
		{
			pre->next = p;   // p所指的结点加入和多项式
			pre = p;         // pre向后移动,尾插
			p = p->next;     // 扫描下一个p
		}
		else if (p->exp == q->exp)  // 系数相等,对应系数相加
		{
			sum = p->coef + q->coef;
			if (sum != 0)
			{
				p->coef = sum;   // 修改p
				pre->next = p;   // 将p加入表尾
				pre = p;
				p = p->next;     // p向后移动
				temp = q;
				q = q->next;
				free(temp);      // 释放系数相同的q结点
 
			}
			else
			{
				// 如果系数相同
				temp = p;
				p = p->next;
				free(temp); 
				temp = q;
				q = q->next;
				free(temp);
			}
		}
		else
		{
			pre->next = q; 
			pre = q;        
			q = q->next;
		}	
	}
	if (p != NULL)
		pre->next = p;
	else
		pre->next = q;
	
}
// 插入
void Attach(int c, int e, Polylist* pRear)
{
	Polynode *P;
    P = (Polynode*)malloc(sizeof(Polynode));
	P->coef = c;
	P->exp = e;
	P->next = NULL;
	(*pRear)->next = P;
	*pRear = P;
}
 
void clearPoly(Polylist poly)
{
	Polynode* pTemp = poly;
	while (poly)
	{
		pTemp = poly;
		// 向后移动
		poly = poly->next;
		free(pTemp);
	}
}
 
void PrintPoly(Polylist poly)
{
	Polynode *p;
	p = poly->next;
	if (!p)
	{
		printf("0 0\n");
		return;
	}
	printf("%d", p->coef);
	printf(" %d", p->exp);
	p = p->next;
	while (p != NULL)
	{
		printf(" %d", p->coef);
		printf(" %d", p->exp);
		p = p->next;
	}
	printf("\n");
}
 
Polylist PolyMult(Polylist polya, Polylist polyb)
{
	Polylist polyc;
	Polynode *p, *q, *temp, *Rear;
	int coef, exp;
	InitPoly(&polyc);
	Rear = polyc;
	p = polya->next; 
	q = polyb->next; 
	if (!p||!q)
	{
		return polyc;
	}
	q = polyb->next;
	while (q)
	{
		Polynode *P;
		P = (Polynode*)malloc(sizeof(Polynode));
		P->coef = p->coef*q->coef;
		P->exp = p->exp+q->exp;
		P->next = NULL;
		Rear->next = P;
		Rear = P;
		q = q->next;
	}
	p = p->next;
	// 将元素插入
	while (p)
	{
		q = polyb->next;
		Rear = polyc;
		while (q)
		{
			exp = p->exp + q->exp;
			coef = p->coef*q->coef;
			while (Rear->next&&Rear->next->exp > exp)
			{
				Rear = Rear->next;
			}
			if (Rear->next&&Rear->next->exp == exp)
			{
				// 对应系数不为0
				if (Rear->next->coef + coef)
				{
					Rear->next->coef += coef;
				}
				// 删去这个节点
				else
				{
					temp = Rear->next;
					Rear->next = temp->next;
					free(temp);
				}
			}
			// 如果这个指数不存在,添加这个节点到链表中
			else
			{
				temp = (Polynode*)malloc(sizeof(Polynode));
				temp->coef = coef;
				temp->exp = exp;
				temp->next = Rear->next;
				Rear->next = temp;
				Rear = Rear->next;
			}
			q = q->next;
		}
		p = p->next;
	}
	return polyc;
	
	
}
 
 
 
 
 
int main()
{
	Polylist Polya, Polyb, Polyc;
	int n, m;
	InitPoly(&Polya);
	InitPoly(&Polyb);
	InitPoly(&Polyc);
	scanf("%d", &n);
	PolyCreate(Polya, n);
	scanf("%d", &m);
	PolyCreate(Polyb, m);
	Polyc = PolyMult(Polya, Polyb);
	PrintPoly(Polyc);
	Polyadd(Polya, Polyb);
	PrintPoly(Polya);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值