首页 > 其他分享 >#C语言结构体/结构体指针/单链表学习必备总结(浓缩版)#

#C语言结构体/结构体指针/单链表学习必备总结(浓缩版)#

时间:2024-06-16 20:03:45浏览次数:21  
标签:结点 单链 struct int C语言 printf next LinkNode 结构

一.结构体的定义

结构体是一种用户自定义的数据类型,用于将多个不同类型的数据组合在一起形成一个新的数据类型。结构体由多个成员变量组成,每个成员变量可以是不同的数据类型,可以是基本数据类型(如整型、浮点型、字符型等)或其他结构体类型。结构体的成员变量在内存中是按照声明的顺序依次存储的。

1.结构体的声明初始化:

结构体是一种数据类型,也就是说可以用它来定义并且存储变量。

结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据、需要存储空间;

struct 结构体名 {

类型 成员1;

类型 成员2;

...

};

1.第一种方式:

struct   结构体名  结构体变量名;

#include <stdio.h>
struct date {
	int month;
	int year;
	int tall;
};
int main()
{
	struct date ax1;
	ax1.month = 5;
	ax1.tall = 180;
	ax1.year = 2024;

	struct date ax2 = { 5,2024,180 };

	struct date ax3 = { ax3.month = 5,ax3.year = 2024,ax3.tall = 180 };
	printf("%i\n%i\n%i\n", ax1.month, ax1.tall, ax1.year);
	printf("%i\n%i\n%i\n", ax2.month, ax2.tall, ax2.year);
	printf("%i\n%i\n%i\n", ax3.month, ax3.tall, ax3.year);
	return 0;
}
2.第二种方式:

struct 结构体名{

类型 成员;

类型 成员;
}结构体变量;

#include <stdio.h>
struct date {
	int month;
	int year;
	int tall;
}ax1,ax2,ax3;
int main()
{
//	struct date ax1;
	ax1.month = 5;
	ax1.tall = 180;
	ax1.year = 2024;

//	struct date ax2 = { 5,2024,180 };
	ax2={5,2024,180};

//	struct date ax3 = { ax3.month = 5,ax3.year = 2024,ax3.tall = 180 };
	ax3={ax3.month = 5,ax3.year = 2024,ax3.tall=100};
	
	
	printf("%i\n%i\n%i\n", ax1.month, ax1.tall, ax1.year);
	printf("%i\n%i\n%i\n", ax2.month, ax2.tall, ax2.year);
	printf("%i\n%i\n%i\n", ax3.month, ax3.tall, ax3.year);
	return 0;
}

2.结构体与指针的羁绊:

结构体类型指针访问成员的获取和赋值形式:

(1)(*p). 成员名(.的优先级高于*,(*p)两边括号不能少)

(2)   p->成员名(->指向符)

1.我们可以在结构体中存储指针:
#include <stdio.h>

struct Node
{
 int data;
 struct Node* next; 
}n1;
int main()
{
	n1={10,NULL};
	struct Node n2 = {20 , NULL};
	
	printf("%d %p\n",n1.data,n1.next);
	printf("%d %p",n2.data,n2.next);
	
	return 0;
}

2结构体类型也可以定义为结构体类型指针:
#include<stdio.h>

struct Inventory
{
	char description[10];
	int quantity;
};
int main()
{
	struct Inventory ax={"anxian",30
	};
	struct Inventory *stp=&ax;

	printf("%s %d\n", stp->description, stp->quantity);
	printf("%s %d\n", (*stp).description, (*stp).quantity);
	return 0;
}

3.与数据结构的羁绊

1.typedef----首先我们先介绍一个数据结构常客--

它的英文翻译是 “类型定义”。下面就来看看它的用法。

  typedef int anxian

此时我们就可以将anxian,来代表int这个数据类型。我们来看代码实现:

#include<stdio.h>
typedef int anxian;
int main()
{
	
	anxian a = 6;
	printf("%d",a);
	return 0;
}
2.在结构体中的使用:
typedef struct people {
	int age;
	char sex;
} chinese;

前面的是

typedef                        int                    anxian

而这里同理

typeddef             struct people           chinese

3.现在我们来看单链表
typedef int ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode* next;		
} LinkNode;					

在这个单链表的结构体声明中,struct LNode表示链表的结点结构体,包含两个成员变量:

1.ElemType data:用于存储结点中的数据元素。在这里,ElemType 被定义为 int 类型,因此 data 是一个整型数据成员,用于存储结点中的数据。

2.struct LNode* next:指向后继结点的指针。这个成员变量是一个指针类型,指向下一个结点的地址。通过这个指针,可以实现链表中结点之间的连接,从而形成链表的数据结构。

因此,整体来看,这个单链表的结点结构体 struct LNode 包含了一个数据成员 data 用于存储数据,以及一个指针成员 next 用于指向下一个结点,从而实现链表中结点之间的连接。这种结构体嵌套结构体的方式,可以方便地表示链表的逻辑结构,使得链表的操作更加方便和灵活。

在这里我补充一点:

结构体里面是有一个数据域和一个指针域 是由数据类型和变量名构成。

 int                                  data

struct Lnode *                 next

#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode* next;		//指向后继结点
} LinkNode;					//声明单链表结点类型
void CreateListF(LinkNode*& L, ElemType a[], int n)
//头插法建立单链表
{
	LinkNode* s;
	L = (LinkNode*)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点s
		s->data = a[i];
		s->next = L->next;			//将结点s插在原开始结点之前,头结点之后
		L->next = s;
	}
}
void CreateListR(LinkNode*& L, ElemType a[], int n)
//尾插法建立单链表
{
	LinkNode* s, * r;
	L = (LinkNode*)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
	r = L;					//r始终指向终端结点,开始时指向头结点
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点s
		s->data = a[i];
		r->next = s;			//将结点s插入结点r之后
		r = s;
	}
	r->next = NULL;			//终端结点next域置为NULL
}
void InitList(LinkNode*& L)
{
	L = (LinkNode*)malloc(sizeof(LinkNode));  	//创建头结点
	L->next = NULL;
}
void DestroyList(LinkNode*& L)
{
	LinkNode* pre = L, * p = pre->next;
	while (p != NULL)
	{
		free(pre);
		pre = p;
		p = pre->next;
	}
	free(pre);	//此时p为NULL,pre指向尾结点,释放它
}
bool ListEmpty(LinkNode* L)
{
	return(L->next == NULL);
}
int ListLength(LinkNode* L)
{
	LinkNode* p = L; int i = 0;
	while (p->next != NULL)
	{
		i++;
		p = p->next;
	}
	return(i);
}
void DispList(LinkNode* L)
{
	LinkNode* p = L->next;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode* L, int i, ElemType& e)
{
	int j = 0;
	LinkNode* p = L;
	if (i <= 0) return false;		//i错误返回假
	while (j < i && p != NULL)
	{
		j++;
		p = p->next;
	}
	if (p == NULL)				//不存在第i个数据结点
		return false;
	else						//存在第i个数据结点
	{
		e = p->data;
		return true;
	}
}
int LocateElem(LinkNode* L, ElemType e)
{
	LinkNode* p = L->next;
	int n = 1;
	while (p != NULL && p->data != e)
	{
		p = p->next;
		n++;
	}
	if (p == NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode*& L, int i, ElemType e)
{
	int j = 0;
	LinkNode* p = L, * s;
	if (i <= 0)
		return false;			//i错误返回假
	while (j < i - 1 && p != NULL)		//查找第i-1个结点p
	{
		j++;
		p = p->next;
	}
	if (p == NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点*p
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点*s
		s->data = e;
		s->next = p->next;			//将s结点插入到结点p之后
		p->next = s;
		return true;
	}
}
bool ListDelete(LinkNode*& L, int i, ElemType& e)
{
	int j = 0;
	LinkNode* p = L, * q;
	if (i <= 0)
		return false;		//i错误返回假
	while (j < i - 1 && p != NULL)	//查找第i-1个结点
	{
		j++;
		p = p->next;
	}
	if (p == NULL)				//未找到位序为i-1的结点
		return false;
	else						//找到位序为i-1的结点p
	{
		q = p->next;				//q指向要删除的结点
		if (q == NULL)
			return false;		//若不存在第i个结点,返回false
		e = q->data;
		p->next = q->next;		//从单链表中删除q结点
		free(q);				//释放q结点
		return true;
	}
}
int main()
{
	LinkNode* L;
	ElemType e;
	ElemType a[] = { 1,2,3,4 };
	CreateListF(L, a, 4);        //尾插法建立链表 
	printf("尾插法所得顺序为: ");
	DispList(L);
	DestroyList(L);
	CreateListR(L, a, 4);        //头插法建立链表 
	printf("头插法所得顺序为:");
	DispList(L);
	printf("链表的长度为:%d\n", ListLength(L));
	ListInsert(L, 4, 5);          //在链表第四个元素前插入5 
	printf("插入一个元素后链表的元素为:");
	DispList(L);
	ListDelete(L, 1, e);          //删除链表中第一个元素,并将它的值赋给e 
	printf("删除的元素为:%d\n", e);
	printf("删除一个元素后链表的元素为:");
	DispList(L);
	printf("当前链表是否为空:%d\n", ListEmpty(L));
	GetElem(L, 1, e);
	printf("链表第一个元素为:%d\n", e);
	printf("值为2的元素在链表中的位置为:%d\n", LocateElem(L, 2));
	return 0;
}

标签:结点,单链,struct,int,C语言,printf,next,LinkNode,结构
From: https://blog.csdn.net/2302_79847831/article/details/139720847

相关文章

  • 云计算【第一阶段(14)】Linux的目录和结构
    一、Liunx目录结构1.1、linux目录结构linux目录结构是树形目录结构根目录(树根)所有分区,目录,文件等的位置起点整个树形目录结构中,使用独立的一个"/",表示1.2、常见的子目录必须知道目录路径目录作用/root系统管理员root的宿主目录/home普通用户的宿主目录/boot系统内核、......
  • 学习C语言两个月后的收获(篇目三) #算术操作符 #强制类型转换 #关系操作符 #条件操作符
    一.算术操作符1.双目操作符:+、-、*、/、%注:双目操作符,顾名思义就是有两个操作数的操作符a./:除号。分为整数的除法和小数的除法整数的除法:'/'两边的操作数是整除故而进行整数的除法。整数的除法取值规则:不管余数是多少,不会四舍五入,直接舍弃余数部分而得到......
  • 【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) C语言代码实现[思路+代码]
    【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客JS、Java、C、python、C++代码实现:【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II)JavaScript代码实现[思......
  • (pdf)数据结构与算法分析 Java语言描述=Data Structures and Algorithm Analysis in Jav
    书:pan.baidu.com/s/1tGbGhhQ3Ez1SIkqdEREsjQ?pwd=eqp0提取码:eqp0数组:作为最基本的数据结构,用于存储固定大小的同类型元素集合。链表:动态数据结构,允许在任意位置插入和删除元素。栈:后进先出(LIFO)的数据结构,常用于函数调用和表达式求值。队列:先进先出(FIFO)的数据结构,常用于任务调......
  • 趣味C语言——【关机代码】
    ......
  • 趣味C语言——【猜数字】小游戏
    ......
  • C语言基础--结构体
    一、结构体定义1、结构体是对数据类型的拓展,在一个结构体可以存放多样类型的数据。 2、结构体定义格式struct结构体名{类型成员变量1;类型成员变量2;.......};typedefenumcard_type{身份证,学......
  • 1832javaERP管理系统之车间计划管理Myeclipse开发mysql数据库servlet结构java编程计算
    一、源码特点 javaerp管理系统之车间计划管理是一套完善的web设计系统,对理解JSPjava编程开发语言有帮助采用了serlvet设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql,使用java语言开发。......
  • C语言考试内容
    C语言考试通常会涵盖以下几个主要方面:1.**基本概念**:  -C语言的历史和特点  -C语言的编译过程  -程序的基本结构(包括预处理指令、主函数main()、函数定义等)2.**数据类型和运算符**:  -基本数据类型(整型、浮点型、字符型等)  -指针和数组  -运......
  • C语言指针与数组的区别
    在C语言中,指针和数组虽然在很多情况下可以互换使用,但它们在概念上和行为上存在一些区别。下面详细解释这些区别:###数组1.**固定大小**:数组在声明时必须指定大小,这个大小在编译时确定,之后不能改变。2.**连续内存**:数组中的元素在内存中是连续存储的。3.**类型**:数组名代......