栈,队列,链表

220 阅读5分钟

二:栈,队列和链表

1.栈

1.1:什么是栈?

栈是一种后进先出的数据结构,且它限定为只能在一端进行插入和删除。

例子:比如说装羽毛球的盒子,打开一端,先放进去的羽毛球只能在在最后被取出。

1.2:图解

1.3 : 如何解决栈溢出问题和访问栈顶元素

#include<iostream>
#include<vector>
using namespace std;
struct Stack{
	int data[10000];
	int top = -1;
	void push(int x){
		top++;
		if(top < 10000){
			data[top] = x;
		}else{
			top--;
			cout << "Stack overflow" << endl;
		}
	}
	void pop(int x){
		if(top >= 0){
			top--;
		}	
	}
	int topval(){
		if(top >= 0){
			return data[top];
		}
	}
};
int main(){
	Stack s;
	for(int i = 1;i <= 10;i++){
		s.push(i);
	}
	for(int i = 1;i <= 10;i++){
		cout << s.topval() << ' ';
		s.top--;
	}
	return 0;
}

1.4: 题目:如何来判断一段字符串是否是回文

/回文是指正读和反读均相同的字符序列/

代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
    char a[101],s[101];
    int i,len,mid,next,top;
    gets(a);
    len = strlen(a);
    mid = len / 2 - 1;
    top = 0;
    for(i = 0;i <= mid;i++)
    {
        top++;
        s[top] = a[i];
    }
    if(len % 2 == 0)
    {
        next = mid  + 1;
    }
    else
    {
        next = mid + 2;
    }
    for(i = next;i <= len-1;i++)
    {
        if(a[i] != s[top])
            break;
        top--;
    }
    if(top == 0)
    {
        printf("Yes");
    }
    else
    {
        printf("No");
    }
    return 0;
}

2.队列

2.1: 什么是队列?

队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这叫做'出队',而只能在队列的尾部(tail)进行插入操作,这叫做‘入队’,当队列中为空时,我们称它为空队列。

2.2 图解

2.3: 例题 :

输入一串数,将第一个数删除,将第二个数放到这串数字的末尾,再将第三个数删除并将第四个数放到这串数字的末尾,再将第五个数删除……,直到剩下最后一个数,将最后一个数也删除,按照删除的顺序,将这些删除的数连在一起并输出。

代码如下:

#include<stdio.h>
int main()
{
    int q[102] = {0,6,3,1,7,5,9,8,4,2},head,tail;
    head = 1;
    tail = 10;
    while(head < tail)
    {
        printf("%d ",q[head]);
        head++;
        q[tail] = q[head];
        tail++;
        head++;
    }
    return 0;
}

2.4 : 思路

队列遵循的是FIFO原则,即First in First out,那么我们就可以创建一个队列,将数据入队,因为我习惯于把数组从1号单元开始使用,所以在前面加一个0占着0号单元,将9个数全部放进队列以后head = 1,tail = 10,如果要删除一个数的话,现在只需要将head++就可以了,要是想新增加一个数的话只需要将tail++就可以了.

2.5!!!队列的尾部永远都指向队列最后一个元素的下一个位置。

/我们也可以将队列进行封装成一个结构体进行使用/

2.6:图示

代码如下:

#include<stdio.h>
struct queue{
    int data[100];
    int head;
    int tail;
};
int main()
{
    struct queue q;
    int i;
    q.head = 1;
    q.tail = 1;
    for(i = 1;i <= 9;i++)
    {
        scanf("%d",&q.data[q.tail]);
        q.tail++;
    }
    while(q.head < q.tail)
    {
        printf("%d ",q.data[q.head]);
        q.head++;
        q.data[q.tail] = q.data[q.head];
        q.tail++;
        q.head++;
    }
    return 0;
}

2.7 总结:

上面这个方法可以加助对队列的理解,队列的三个基本元素是一个数组和两个变量,C++的STL库里已经有了队列的实现,且队列是广度优先算法(BFS)以及队列优化的Bellman-Ford最短路径算法的核心数据结构.

3.链表

3.1 :什么是链表?

图解:

如果想要插入一个数的时候使用数组,就需要把每一个数进行移位,而使用链表以后只需要更改一下就可以了,大大的节省了时间。

3.2:什么是指针?

指针有什么作用?答案很多人都知道:存储地址,准确的说是存储一个内存空间的地址,使用'*'来定义一个指针变量,即定义一个指针,例如:

double *p;

那么指针如何存储a的地址呢?

p = &a;

&是取地址符,这样p就获得了a的地址,我们形象的称为p指向了a.

3.3 :如何动态存储变量?

我们在程序中存储一个数5的时候,除了使用int a这种在内存中申请一块区域来存放的方式以外,还有着另外一种动态存储方法。

malloc(4);

malloc函数的作用是从内存中申请分配指定字节大小的内存空间,上面这一行就申请了4个字节,int变量就是四个字节的,如果你不知道,没有关系,我们可以使用sizeof(int)来获取int类型变量所占用的字节数,如:

malloc(sizeof(int));

现在已经申请了四个字节的变量用来存储一个整数,接下来就需要对这个内存空间进行操作了,这里我们就需要一个指针来指向这个空间,也就是存储这个空间的首地址.

int *p;
p = (int *)maoolc(sizeof(int));

(int *)是强制类型转换,malloc函数的返回值类型是void *型,在C和C++中,void *类型可以强制转换为任何类型.

3.4 :链表的存储

Note:链表的每一个节点都由两部分组成,数据域和指针域,数据域用来存放具体的数值,指针域用来存放下一个结点的地址,也称为前驱和后继.

代码如下:

#include<stdio.h>
#include<stdlib.h>
struct node{
    int data;
    struct node *next;
};
int main()
{
    struct node *head,*p,*q,*t;
    int i,n,a;
    scanf("%d",&n);
    head = NULL;
    for(i = 1;i <= n;i++)
    {
        scanf("%d",&a);
        p = (struct node *)malloc(sizeof(struct node));
        p -> data = a;
        p -> next = NULL;
        if(head == NULL)
        {
            head = p;
        }
        else
        {
            q -> next = p; 
        }
        q = p;
    }
    t = head;
    while(t != NULL)
    {
        printf("%d ",t ->data);
        t = t->next;
    }
    return 0;
}

/声明/:上面的代码没有使用释放动态申请的空间,虽然没有错误,但是会很不安全,可以使用free命令进行释放.

3.5 :链表的插入

代码如下:

#include<stdio.h>
#include<stdlib.h>
struct node{
	int data;
	struct node *next;
};
int main()
{
	struct node *head,*p,*q,*t;
	int n,a;
	scanf("%d",&n);   //n表示输入n个数
	head = NULL;
	for(int i = 1;i <= n;i++)
	{
		scanf("%d",&a);    
		p = (struct node *)malloc(sizeof(struct node));
		p -> data = a;
		p -> next = NULL;
		if(head == NULL)
		{
			head = p;
		}
		else
		{
			q -> next = p;
		}
		q = p;
	}
	scanf("%d",&a);
	t = head;
	while(t != NULL)
	{
		if(t -> next == NULL || t -> next -> data > a)
		{
			p = (struct node *)malloc(sizeof(struct node));
			p -> data = a;
			p -> next = t -> next;
			t -> next = p;
			break;
		}
		t = t->next;
	}
	t = head;
	while(t != NULL)
	{
		printf("%d ",t -> data);
		t = t->next;
	}
	return 0;
}