数据结构--栈和队列

发布于:2025-06-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

链栈

头文件

#ifndef __LINKS_H__
#define __LINKS_H__
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
	int data;
	struct node *next;
}node,*node_p;
//1、创建结点
node_p create_node(int value);
//2、判空
int empty_stack(node_p S);
//3、入栈
void push_stack(node_p *S,int value);
//4、出栈
int pop_stack(node_p *S);





#endif

主函数文件

#include "links.h"
int main()
{
	//申请栈顶指针初始值为NULL
	//刚申请栈顶指针时,栈中没有元素
	node_p S = NULL;
	push_stack(&S,12);
	push_stack(&S,90);
	printf("%d\n",pop_stack(&S));
	push_stack(&S,26);
	printf("%d\n",pop_stack(&S));
	printf("%d\n",pop_stack(&S));
	return 0;
}

功能函数文件

#include "links.h"
//1、创建结点
node_p create_node(int value)
{
	node_p new = (node_p)malloc(sizeof(node));
	if(new==NULL){return NULL;}
	new->next = NULL;
	new->data = value;
	return new;
}
//2、判空
int empty_stack(node_p S)
{
	return S==NULL;
}
//3、入栈
//入栈操作需要修改主函数中栈顶指针的指向
void push_stack(node_p *S,int value)
{
	//S是一个二级指针,保存主函数内栈顶指针的地址
	if(S==NULL){return;}
	//不用判断*S,因为如果*S==NULL说明栈中没有元素
	node_p new = create_node(value);
	new->next = *S;  //新结点指向原来的栈顶元素
	*S = new;   //让主函数中的栈顶指针S指向新的栈顶结点
}
//4、出栈
int pop_stack(node_p *S)
{
	if(*S==NULL){return -1;}
	if(empty_stack(*S)){return -2;}
	int ret = (*S)->data;
	node_p del = *S;   //先保存栈顶结点
	*S = (*S)->next;     //让栈顶指针向后指一个结点
	free(del);   //释放栈顶元素
	return ret;
}

makefile文件

EXE=link_stack
Objs=$(patsubst %.c,%.o,$(wildcard *.c))
CC=gcc
CFlags=-c -o

all:$(EXE)
$(EXE):$(Objs)                                 
	$(CC) $^ -o $@
%.o:%.c
	$(CC) $^ $(CFlags) $@
.PHONY:clean
clean:
	rm *.o $(Objs)

                                               
                                               

1.什么是计算机的大小端存储

大端存储(Big Endian)
定义:将数据的高位字节存于低地址,低位字节存于高地址,即 “高字节在前”。
类比:类似人类阅读习惯(从左到右读高位),如数字 “1234” 写作 “12 34”。

小端存储(Little Endian)
定义:将数据的低位字节存于低地址,高位字节存于高地址,即 “低字节在前”。
类比:类似逆序存储,如数字 “1234” 写作 “34 12”。如何判断大小端存

维度 大端存储(Big Endian) 小端存储(Little Endian)
存储顺序 高位字节→低位字节(从低地址到高地址) 低位字节→高位字节(从低地址到高地址)
逻辑顺序 与数据的二进制表示顺序一致 与数据的二进制表示顺序相反
典型场景 网络协议、PowerPC/MIPS 架构、BMP 文件 x86/AMD64 架构、ARM(默认)、PE 文件
访问效率 需按字节顺序读取,可能增加处理开销 低地址优先访问,符合 CPU 缓存预取策略

2.如何判断大小端存储  

#include <stdio.h>

int isLittleEndian() {
    unsigned int num = 1;  // 0x00000001 (32位整数)
    unsigned char* ptr = (unsigned char*)&num;  // 指向最低地址字节
    
    // 小端:低字节在前 -> 第一个字节是0x01
    // 大端:高字节在前 -> 第一个字节是0x00
    return (*ptr == 1);
}

int main() {
    if (isLittleEndian()) {
        printf("小端存储(低字节在前)\n");
    } else {
        printf("大端存储(高字节在前)\n");
    }
    return 0;
}

通过将整数的地址强制转换为字符指针,访问第一个字节的值:
原理:

小端存储(如 x86)中,0x00000001 的内存布局为 0x01 0x00 0x00 0x00,最低地址字节是 0x01。
大端存储中,内存布局为 0x00 0x00 0x00 0x01,最低地址字节是 0x00。

3.arr和&arr的区别

arr: 数组首元素的地址,指向第一个元素 arr[0]。
&arr:   整个数组的地址,指向包含 N 个元素的数组。

4.解释数组指针、指针数组、函数指针和指针函数的区别

一、数组指针(指向数组的指针)
定义
指向整个数组的指针,类型为 type (*)[N],其中 N 是数组长度。
二、指针数组(元素为指针的数组)
定义
数组的每个元素都是指针,类型为 type* arr[N],其中 N 是数组长度。
三、函数指针(指向函数的指针)
定义
指向函数的指针,可用于动态调用函数。类型为 return_type (*)(parameter_types)。
四、指针函数(返回指针的函数)
定义
返回值为指针的函数,本质是函数,类型为 type* func(params)。

5. char str[]="hello\O1";printf("strlen(str)");的结果

6

思维导图


网站公告

今日签到

点亮在社区的每一天
去签到