慕课(第二章)

线性结构:
线性结构是一个有序数据元素的集合。
常用的线性结构有:线性表,栈,队列,双队列,串。
关于广义表、数组,是一种非线性的数据结构。
常见的非线性结构有:二维数组,多维数组,广义表,树(二叉树等)。

分类:
数据结构课程中数据的逻辑结构分为线性结构和非线性结构。
对于数据结构课程而言,简单地说,线性结构是n个数据元素的有序(次序)集合。

特征:
1.集合中必存在唯一的一个"第一个元素";
2.集合中必存在唯一的一个"最后的元素";
3.除最后元素之外,其它数据元素均有唯一的"后继";
4.除第一元素之外,其它数据元素均有唯一的"前驱"。
数据结构中线性结构指的是数据元素之间存在着“一对一”的线性关系的数据结构。
如(a0,a1,a2,…,an),a0为第一个元素,an为最后一个元素,此集合即为一个线性结构的集合。
相对应于线性结构,非线性结构的逻辑特征是一个结点元素可能对应多个直接前驱和多个后继。

1.线性表:
线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点)。

储存:
线性表可以用数组进行存储。

查找:
从头到尾一个个进行查找,复杂度为O(n)。

插入:
将相应位置之后的数据全部向后挪一位,记得要从后向前挪动。

for(i=n+1;i>t;i--)
a[i]=a[i-1];

删除:
将相应位置之后的数据往前挪动一位,从前向后挪动。

for(i=n;i<t;i++)
a[i]=a[i+1];

堆栈:
堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。

堆栈存储:
就像一个桶子,往里面放东西,先放进去的后面才能拿出来,也就是‘先进后出’。

堆的申请:

p1 = (char *)malloc(10);

2.队列
先进者先出,就是"队列" 我们可以想象成,排队买票,先来的先买,后来的只能在末尾,不允许插队。

队列的两个基本操作:入队 将一个数据放到队列尾部;出队 从队列的头部取出一个元素。队列也是一种操作受限的线性表数据结构 它具有先进先出的特性,支持队尾插入元素,在队头删除元素。

队列的概念很好理解,队列的应用也非常广泛如:循环队列、阻塞队列、并发队列、优先级队列等。

队列可以用数组Q[1…m]来存储,数组的上界m即是队列所容许的最大容量。在队列的运算中需设两个指针:head,队头指针,指向实际队头元素;tail,队尾指针,指向实际队尾元素的下一个位置。一般情况下,两个指针的初值设为0,这时队列为空,没有元素。数组定义Q[1…10]。Q(i) i=3,4,5,6,7,8。头指针head=2,尾指针tail=8。队列中拥有的元素个数为:L=tail-head。现要让排头的元素出队,则需将头指针加1。即head=head+1这时头指针向上移动一个位置,指向Q(3),表示Q(3)已出队。如果想让一个新元素入队,则需尾指针向上移动一个位置。即tail=tail+1这时Q(9)入队。当队尾已经处理在最上面时,即tail=10,如果还要执行入队操作,则要发生"上溢",但实际上队列中还有三个空位置,所以这种溢出称为"假溢出"。
克服假溢出的方法有两种。一种是将队列中的所有元素均向低地址区移动,显然这种方法是很浪费时间的;另一种方法是将数组存储区看成是一个首尾相接的环形区域。当存放到n地址后,下一个地址就"翻转"为1。在结构上采用这种技巧来存储的队列称为循环队列。

下面给一个例子,充分运用了堆栈和队列:

队列和栈是两种重要的数据结构,它们具有push k和pop操作。push k是将数字k加入到队列或栈中,pop则是从队列和栈取一个数出来。队列和栈的区别在于取数的位置是不同的。

队列是先进先出的:把队列看成横向的一个通道,则push k是将k放到队列的最右边,而pop则是从队列的最左边取出一个数。

栈是后进先出的:把栈也看成横向的一个通道,则push k是将k放到栈的最右边,而pop也是从栈的最右边取出一个数。

假设队列和栈当前从左至右都含有1和2两个数,则执行push 5和pop操作示例图如下:

      push 5          pop

队列 1 2 -------> 1 2 5 ------> 2 5

      push 5          pop

栈 1 2 -------> 1 2 5 ------> 1 2

现在,假设队列和栈都是空的。给定一系列push k和pop操作之后,输出队列和栈中存的数字。若队列或栈已经空了,仍然接收到pop操作,则输出error。

Input
第一行为m,表示有m组测试输入,m<100。
每组第一行为n,表示下列有n行push k或pop操作。(n<150)
接下来n行,每行是push k或者pop,其中k是一个整数。
(输入保证同时在队列或栈中的数不会超过100个)
Output
对每组测试数据输出两行,正常情况下,第一行是队列中从左到右存的数字,第二行是栈中从左到右存的数字。若操作过程中队列或栈已空仍然收到pop,则输出error。输出应该共2*m行。
Sample Input
2
4
push 1
push 3
pop
push 5
1
pop
Sample Output
3 5
1 5
error
error

#include<stdio.h>
int main()
{
    int j,n,i,t;
    scanf("%d",&n);
    for(j=0; j<n; j++)
    {
        int m,x,y,a[10000]= {0},b[10000]= {0},head=0,last=0,k=0,flag=0;
        char p[200];
        scanf("%d",&m);
        for(x=0; x<m; x++)
        {
            scanf("%s",p);
            if(p[1]=='u')
            {
                scanf("%d",&t);
                a[last]=t;
                last++;
                b[k]=t;
                k++;
            }
            else if(p[1]=='o')
            {
                if(flag==1)
                continue;
                if(last==head)
                {
                    printf("error\n");
                    flag=1;
                }
                else
                {
                    head++;
                }
                if(k==0)
                {
                    printf("error\n");
                    flag=1;
                }
                else
                    k--;
            }
        }
        if(flag) continue;
        if(last!=head&&flag==0)
        {
            for(i=head; i<last; i++)
                printf("%d ",a[i]);
            printf("\n");
        }
        if(k!=0&&flag==0)
        {
            for(i=0; i<k; i++)
                printf("%d ",b[i]);
            printf("\n");
        }
    }
    return 0;
}

这里没有运用链表而是用的数组,方法很简单,用两个数组存数据,一个运用堆栈的思想,另外一个运用队列的思想,当用堆栈时,就last–,用队列时就head++
思维清晰,代码相对较容易。

多项式乘法与加法:

定义一个结构体来存系数和指数,加法就是让相同指数的的相应系数相加,乘法就是每一个项与另外一个式子的其他项相乘。

typedef struct Node *PNode;		                            //节点指针类型
struct Node{
	int exp;						    //存储每一项的指数
	float coe;						    //存储每一项的系数
	PNode next;						    //指向下一项(下一个节点)
};

求和函数:

PNode addpoly(PNode h1, PNode h2)
{
	PNode p, r = NULL, s1, s2, s = NULL;
	float c;
	int e;
	s1 = h1;
	s2 = h2;
	while (s1 != NULL&&s2 != NULL)
	{
		if (s1->exp == s2->exp)
		{
			c = s1->coef+s2->coef;
			e = s1->exp;
			s1 = s1->next;
			s2 = s2->next;
		}
		else if (s1->exp > s2->exp)
		{
			c = s1->coef;
			e = s1->exp;
			s1 = s1->next;
		}
		else
		{
			c = s2->coef;
			e = s2->exp;
			s2 = s2->next;
		}
		if (c != 0)
		{
			p = (PNode)malloc(sizeof(struct Node));
			p->coef = c;
			p->exp = e;
			p->next = NULL;
			if (s == NULL)
				s = p;
			else
				r->next = p;
			r = p;
		}
	}
	while (s1 != NULL)
	{
		c = s1->coef;
		e = s1->exp;
		s1 = s1->next;
		if (c != 0)
		{
			p = (PNode)malloc(sizeof(struct Node));
			p->coef = c;
			p->exp = e;
			p->next = NULL;
			if (s == NULL)
				s = p;
			else
				r->next = p;
			r = p;
		}
	}
	while (s2 != NULL)
	{
		c = s2->coef;
		e = s2->exp;
		s2 = s2->next;
		if (c != 0)
		{
			p = (PNode)malloc(sizeof(struct Node));
			p->coef = c;
			p->exp = e;
			p->next = NULL;
			if (s == NULL)
				s = p;
			else
				r->next = p;
			r = p;
		}
	}
	return s;
}
发布了13 篇原创文章 · 获赞 0 · 访问量 348

猜你喜欢

转载自blog.csdn.net/JSUChengyuezhen/article/details/104395396
今日推荐