首页 > 其他分享 >链表表示和实现

链表表示和实现

时间:2023-09-10 12:11:13浏览次数:33  
标签:NODE 表示 结点 实现 head next 链表 指针

链表表示和实现

单链表的按值查找

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

struct node {
	int data;
	struct node *next;
};
typedef struct node NODE;

NODE* create() {
	int t;
	NODE *head, *p, *q;
	head = (NODE*)malloc(sizeof(NODE));

	p = head;
	while (1) {
		printf("输入链表需要存放的数(输入负数结束)");
		scanf("%d", &t);
		if (t < 0) {
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));
		q->data = t;
		p->next = q;
		p = q;
	}
	p->next = NULL;

	return head;
}

void print(NODE* head) {
	int t;
	NODE* p;
	p = head->next;
	while (p != NULL) {
		t = p->data;
		printf("%d ", t);
		p = p->next;

	}
	printf("\n");
}
/*
这是一个在链表按值查找目标元素的的函数
该函数需要链表的头指针,和需要查找的元素
该函数将返回目标节点的地址
*/
NODE* search(NODE*head, int e) {
	NODE* p;//定义一个指针来指向需要查找的节点
	p = head->next;//让指针指向首元节点

	while (p != NULL) {//如果p不为空就进行循环
		if (p->data == e) {
			break;//找到了直接跳出循环
		}
		p = p->next;//没找到向后移动指针
	}
	return p;//返回指针的值,如果没找到的话指针的值将为null
}

int main() {
	NODE* head;
	int e;
	head = create();
	print(head);
	scanf("%d", &e);
	printf("%p", search(head, e));//打印出目标元素的地址
	return 0;
}

单链表的按值查找

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

struct node {
	int data;
	struct node *next;
};
typedef struct node NODE;

NODE* create() {
	int t;
	NODE *head, *p, *q;
	head = (NODE*)malloc(sizeof(NODE));

	p = head;
	while (1) {
		printf("输入链表需要存放的数(输入负数结束)");
		scanf("%d", &t);
		if (t < 0) {
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));
		q->data = t;
		p->next = q;
		p = q;
	}
	p->next = NULL;

	return head;
}

void print(NODE* head) {
	int t;
	NODE* p;
	p = head->next;
	while (p != NULL) {
		t = p->data;
		printf("%d ", t);
		p = p->next;

	}
	printf("\n");
}

/*
这是一个在链表按值查找目标元素的的函数
该函数需要链表的头指针,和需要查找的元素
该函数将返回目标节点序号
*/
int search(NODE*head, int e) {
	NODE* p;
	p = head->next;
	int i = 1;//定义一个记录序号的变量,让其初始化为1
	while (p != NULL) {
		if (p->data == e) {
			break;//如果找到了直接跳出循环
		}
		//没找到将指针向后移动,同时i++;
		p = p->next;
		i++;
	}
	if (p == NULL) {//如果p==null说明没找到返回-1
		return -1;
	} else {

		return i;//如果找到了返回i的值
	}

}


int main() {
	NODE* head;
	int e;
	head = create();
	print(head);
	scanf("%d", &e);
	printf("%d", search(head, e));
	return 0;
}

建立两个循环链表,并且将两个链表合并

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

struct node {
	int data;
	struct node* next;

};

typedef struct node NODE;


NODE* create() {
	int t;
	NODE *head, *q, *p, *T;
	//定义头指针,目标节点的指针,尾指针
	//还有需要做为返回值的尾指针T
	head = (NODE*)malloc(sizeof(NODE));
	p = head;

	while (1) {
		scanf("%d", &t);
		if (t == 0) {
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));
		q->data = t;
		p->next = q;
		p = q;
	}
	p->next = head; //和建立单链表不同的是
	//p->next不再指向null,而是直接指向头指针head
	T = p; //将尾指针的值赋值给T,
	return T;//返回循环链表的尾指针
}

/*
该函数用来遍历一个循环链表
需要一个参数就是链表的尾指针
该函数没有返回结果
*/
void print(NODE* T) {
	NODE* head, *p;
	//我们还是从head指针开始
	head = T->next;
	//头指针存放在尾指针T的next域里面
	p = head->next; //让p指向首元结点
	int t;

	while (p != head) {
		t = p->data;
		printf("%d ", t);
		p = p->next;
	}

	//因为我们从首元结点开始遍历,但是最后的尾指针指向的不只是null,而是指向
	//了头节点的地址所以循环条件要改成p!=head,其他都相同
}
/*
该函数用来合并两个循环链表,变成一个循环链表
需要合并的两个循环链表的尾指针
该函数将返回合并好的循环链表的尾指针
*/
NODE* combination(NODE* Ta, NODE* Tb) {
	NODE* p_temp;
	p_temp = Ta->next;//定义一个临时变量来储存a链表头节点的地址
	Ta->next = Tb->next->next;//让a链表的尾指针指向b链表的首元节点
	free(Tb->next);//释放b链表的头结点
	Tb->next = p_temp;//让b链表的尾指针所指向的next域指向a链表的头节点
	//这样两个循环链表合并成了一个循环链表
	return Tb;//返回新链表的尾指针
}


int main() {
	NODE *Ta, *Tb, *Tc;
	printf("请创建a链表以0结束\n");
	Ta = create();
	print(Ta);
	printf("\n请创建b链表以0结束\n");
	Tb = create();
	print(Tb);
	Tc = combination(Ta, Tb);
	printf("\n合并完成之后的链表为\n");
	print(Tc);








	return 0;
}

链表的操作

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

struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

//链表的创建
NODE* create() {
	int t;//定义临时数据变量
	NODE *head, *p, *q;//定义头指针head,末尾指针p,以及临时指针q.
	head = (NODE*)malloc(sizeof(NODE));
	//分配一个头结点,并且让头指针指向头结点
	p = head;//让末尾指针也指向头结点
	
	while (1) {
		printf("请输入链表元素(输入负数结束):\n");
		scanf("%d", &t);
		if (t < 0) {//如果搜集到负数;
			p->next = NULL; //末尾指针所指向的指针域的值为null;
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));//每次循环分配一个结点,并且让临时指针q指向该结点
		q->data = t;//用这种方式给刚分配的结点赋值,因为q指向该结点
		p->next = q;//让末尾指针的指针域指向刚分配的结点,这样新结点就挂在了链表的后面
		p = q;//移动末尾指针p让它始终指向末尾
	}
	return head;//最后返回该链表的头指针
}

//链表的遍历
void print(NODE *head) {
	//遍历一个链表需要这个链表的头指针
	NODE *p;//定义一个指针变量p,用来作为寻找指针
	p = head->next; //这里是让p指向首结点
	while (p != NULL) { //只要p不为空
		printf("%d ", p->data); //打印出当前的数据域
		p = p->next; //同时指针向后移动。
	}
	
	printf("\n");
}
//链表的删除函数
//需要头指针的值和需要删除元素的值
//该函数没有返回结果nt
void dele(NODE *head, int a) {
	NODE *q, *p; //定义两个指针一个为前驱结点的指针一个为目标结点的指针
	q = head; //让前驱结点指向头结点
	p = q->next; //让q结点指向首结点
	
	while (p != NULL) {
		
		if (p->data == a) { //如果找到了目标结点
			
			q->next = p->next; //直接让前驱结点指向目标结点的后续结点
			free(p);//然后释放目标结点
			break;//跳出循环
		} else {
			q = p; //如果目标指针p,的指针域不是目标值
			//q向后移动一个
			p = p->next;
			//p指向p->next,也是向后移动一个
		}
	}
	if (p == NULL) { //也就是说找到最后都,没找到目标结点
		printf("没有符合条件的结点\n");
	}
}

/*
  在链表中插入结点
  
  在链表中插入结点,是一种非常常见的,相对复杂的链表操作
  
  要想在链表中插入一个新结点,首先必须确定插入的位置
  
  
  
  一般来说通过查找第一个符合条件的结点,来确定插入的位置
  
  
  带头结点的单向链表的插入步骤
  1.首先,为新结点分配内存空间,并且存入数据
  2.在链表中查找与插入位置相对应的目标结点
  3.将新结点插入到目标结点之前(或之后).
  
  在目标结点之后插入新结点,相对容易实现,同时也很少使用
  
  所以我们现在只讨论在目标结点之前插入新结点的情况
  
  
  
  例如在一个带头结点的单向动态链表,所有结点按照数据域的值升序排列
  要求传入一个结点使所有的结点仍然按照数据域的值升序排列
  
  
  1.确定新结点的插入位置
  
  新结点应该插入到所有结点值小于它的结点之后,第一个结点值不小于它的结点之前
  
  由于链表的前端开始查找,按照结点值由大到小的顺序进行比较
  
  因此应该将第一个结点值不小于新结点的结点,作为查找的目标结点
  然后在其前面插入新结点。
  
  
  2.如何在目标结点之前插入新结点?
  要让目标结点的前驱结点的指针域指向新结点,另一方面还要让新结点的指针域指向目标结点
  
  由于在单项链表的结点中只有指向后续结点的指针,而没有指向前驱结点的指针
  因此,无法通过目标结点获得其前驱结点的地址
  
  
  所以,需要定义三个指针变量r,p,q,分别指向新结点,目标结点以及前驱结点
 */
void insert(NODE *head,int t)
{
	//插入链表结点函数,head为头指针,t为待插入结点值
	NODE *p,*q,*r;
	r=(NODE*)malloc(sizeof(NODE));//给新结点分配内存
	//3.动态创建一个新结点,并且使得指针r指向它
	//4.将形参传入的正整数存入新结点的数据域中
	//5.使得指针q,p分别指向头结点以及后续结点;
	r->data=t;//存入数据
	
	q=head;
	p=head->next;
	
	while(p!=NULL){
		
	if(p->data<t){//查找目标结点
		q=p;
		p=p->next;
	}
	else
	{
	break;
	}
	}
	q->next=r;
	r->next=p; 
	//6.若p==null,说明新结点的值很大,转向第九步。
	//7.若p所指向的结点的值小于新结点的值,则使得所指向的p所指向的结点
	//使得p指向下一个结点,

//8.否则,在q所指向的结点之间插入新结点:然后返回主调函数


//q->next=r;
//r->next=p;



	//9.在末结点(即q所指向的结点)之后连接新结点.然后返回主调函数
	
	
//q->next=r;
//r->next=p;

	
	
	
return ;
}


int main() {
	NODE *head;
	
	
	head = create();
	print(head);
	int data;
	while(1){
		printf("请输入插入的正整数(以负数结束):");
		scanf("%d",&data);
		if(data<0){
			break;
		}
		
insert(head,data);//插入新结点
print(head);
	}

	
//	int data;
//	while (1) {
//		printf("输入您想要删除的数据(输入负数结束):\n");
//		scanf("%d", &data);
//		if (data < 0) {
//			break;
//		}
//		dele(head, data);
//		print(head);
//	}
	
	
	return 0;
}

链表的创建和遍历

链表的创建和遍历

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

struct node { //链表节点结构体类型
	int data;//数据域
	struct node *next;//指针域

};
typedef struct node NODE;//定义类型别名

/*
//创建动态链表函数
该函数不需要参数
返回的是一个node类型的指针,也就是头指针
*/

node *create() {

	NODE *head, *p, *q;
	int t;//用于暂存输入的成绩
	head = (NODE*)malloc(sizeof(NODE));//创建头节点
	//让头指针head来指向头节点
	//3.让末节点指针p指向头节点(相当于空链表的末节点)
	p = head;

	while (1) {
		printf("请输入一个整数成绩(以负数结束):");
		scanf("%d", &t);
		//4.输入一个成绩并且暂存
		if (t < 0) {
			break;
		}

		//5.动态创建一个新的节点,并且q指向它
		q = (NODE*)malloc(sizeof(NODE));

		q->data = t;

		//6.将已知的成绩存入新节点的数据域中


		//7.将新节点连接到链表中,使得当前末节点的指针域指向新节点
		p->next = q;
		//8.调整末节点指针的值,使其指向已连接到链表的新节点

		p = q;
		//9.转向第5步,进行循环
		//10.将末节点的指针域赋值为空指针null,作为链表的结束标志


	}

	p->next = NULL; //设置链表的结束标志

	return head;//返回头指针
}


void print(NODE *head) {
	/*
	带头节点的单向链表的遍历步骤
	1.通过头指针找到头节点
	2.若头节点的指针域为空指针结束空链表
	3.否则,跟随链表节点的指针域,找到下一个节点,并输出其数据域的值
	4.遇到链表的结束标志为止
	*/
	//2.定义一个指向链表节点的指针变量p
	NODE *p;
	//3.使指针p指向头结点的后续节点
	p = head->next;
	if (p == NULL) {
		printf("该链表为空!\n");
	} else {
		//输出当前节点的数据
		printf("链表中的数据为:\n");
		while (p != NULL) {

			printf("->%d", p->data);
			//使得p指向下一个节点
			p = p->next;
		}


	}
//4.如果p==null,则输出“链表为空”的信息,然后返回主调函数
//5.输出p所指节点的数据域的值
//6.使得p指向下一个节点。p=p->next;
//7.若p!=NULL,则转向第5步
//8.否则返回主调函数
	return;
}
int main() {
	/*
	这里我们需要定义3个指针变量
	头指针head
	末节点指针p
	新节点指针q
	然后动态创建一个新节点,作为头节点,
	并使用头指针指向头节点
	*/
	NODE *h;
	h = create(); //创建链表获得头指针
	printf("%p", h);
	print(h);//遍历链表,输出数据
	return 0;
}

链表的清除

今天在b站听的数据结构网课讲的链表的清除现在我自己来实现一下


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

struct node
{
	int data;
	struct node* next;
};
typedef struct node NODE;

NODE *create(int n)
{
NODE *head,*p,*q;
	int t;
	head = (NODE*)malloc(sizeof(NODE));	
	p=head;
	for(int i=0;i<n;i++){
		q=(NODE*)malloc(sizeof(NODE));	
		scanf("%d",&t);
		q->data=t;
		p->next=q;
		p=q;
	}
	p->next=NULL;
	return head;
}
void print(NODE*head)
{
	int t;
	NODE *p;
	p=head->next;
//	if(p==NULL){
//		printf("该链表为空链表\n");
//	}
	while(p!=NULL){
		t=p->data;
		printf("%d ",t);
		p=p->next;
	}
	printf("\n");
}
/*
这是一个清除链表的函数
清除就是将链表保留头节点和头指针,同时让头节点的指针域指向null
该函数需要链表的头指针
该函数没有返回结果
*/
void  clear(NODE *L)
{
	//其实清空链表和销毁链表的操作差不多只有一点点不同
	NODE *p,*q;
	//在销毁链表的函数中我们让L始终指向p所指向的后续节点
	//现在我们需要重新定义一个指针q来始终指向p的后续节点
	//因为我们的指针L需要一直保留
	q=L->next;//让q一开始就指首元节点
	
while(q!=NULL){
    p=q;//让p和q指向同一个节点
	q=q->next;//让q向后移动
	free(p);//释放p节点
}
L->next=NULL;//不要忘记将头节点的指针域变为空

printf("链表已经全部清除\n");
printf("L=%p\n",L);
printf("头节点的指针域的地址为%p",L->next);	
}

int main()
{
	int n;
	NODE *head;
	scanf("%d",&n);
	head=create(n);
	print(head);

clear(head);
print(head);	
	
	return 0;
}

链表的删除

链表的删除分享一下

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

struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

//链表的创建
NODE* create() {
	int t;//定义临时数据变量
	NODE *head, *p, *q;//定义头指针head,末尾指针p,以及临时指针q.
	head = (NODE*)malloc(sizeof(NODE));
	//分配一个头结点,并且让头指针指向头结点
	p = head;//让末尾指针也指向头结点

	while (1) {
		printf("请输入链表元素(输入负数结束):\n");
		scanf("%d", &t);
		if (t < 0) {//如果搜集到负数;
			p->next = NULL; //末尾指针所指向的指针域的值为null;
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));//每次循环分配一个结点,并且让临时指针q指向该结点
		q->data = t;//用这种方式给刚分配的结点赋值,因为q指向该结点
		p->next = q;//让末尾指针的指针域指向刚分配的结点,这样新结点就挂在了链表的后面
		p = q;//移动末尾指针p让它始终指向末尾
	}
	return head;//最后返回该链表的头指针
}

//链表的遍历
void print(NODE *head) {
	//遍历一个链表需要这个链表的头指针
	NODE *p;//定义一个指针变量p,用来作为寻找指针
	p = head->next; //这里是让p指向首结点
	while (p != NULL) { //只要p不为空
		printf("%d ", p->data); //打印出当前的数据域
		p = p->next; //同时指针向后移动。
	}

	printf("\n");
}
//链表的删除函数
//需要头指针的值和需要删除元素的值
//该函数没有返回结果nt
void dele(NODE *head, int a) {
	NODE *q, *p; //定义两个指针一个为前驱结点的指针一个为目标结点的指针
	q = head; //让前驱结点指向头结点
	p = q->next; //让q结点指向首结点

	while (p != NULL) {

		if (p->data == a) { //如果找到了目标结点

			q->next = p->next; //直接让前驱结点指向目标结点的后续结点
			free(p);//然后释放目标结点
			break;//跳出循环
		} else {
			q = p; //如果目标指针p,的指针域不是目标值
			//q向后移动一个
			p = p->next;
			//p指向p->next,也是向后移动一个
		}
	}
	if (p == NULL) { //也就是说找到最后都,没找到目标结点
		printf("没有符合条件的结点\n");
	}
}

int main() {
	NODE *head;


	head = create();
	print(head);
	int data;
	while (1) {
		printf("输入您想要删除的数据(输入负数结束):\n");
		scanf("%d", &data);
		if (data < 0) {
			break;
		}
		dele(head, data);
		print(head);
	}


	return 0;
}

链表的删除2

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

struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

//链表的创建
NODE* create() {
	int t;//定义临时数据变量
	NODE *head, *p, *q;//定义头指针head,末尾指针p,以及临时指针q.
	head = (NODE*)malloc(sizeof(NODE));
	//分配一个头结点,并且让头指针指向头结点
	p = head;//让末尾指针也指向头结点
	
	while (1) {
		printf("请输入链表元素(输入负数结束):\n");
		scanf("%d", &t);
		if (t < 0) {//如果搜集到负数;
			p->next = NULL; //末尾指针所指向的指针域的值为null;
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));//每次循环分配一个结点,并且让临时指针q指向该结点
		q->data = t;//用这种方式给刚分配的结点赋值,因为q指向该结点
		p->next = q;//让末尾指针的指针域指向刚分配的结点,这样新结点就挂在了链表的后面
		p = q;//移动末尾指针p让它始终指向末尾
	}
	return head;//最后返回该链表的头指针
}

//链表的遍历
void print(NODE *head) {
	//遍历一个链表需要这个链表的头指针
	NODE *p;//定义一个指针变量p,用来作为寻找指针
	p = head->next; //这里是让p指向首结点
	while (p != NULL) { //只要p不为空
		printf("%d ", p->data); //打印出当前的数据域
		p = p->next; //同时指针向后移动。
	}
	
	printf("\n");
}
//链表的删除函数
//需要头指针的值和需要删除元素的值
//该函数没有返回结果nt
void dele(NODE *head, int a) {
	NODE *q, *p; //定义两个指针一个为前驱结点的指针一个为目标结点的指针
	q = head; //让前驱结点指向头结点
	p = q->next; //让q结点指向首结点
	
	while (p != NULL) {
		
		if (p->data == a) { //如果找到了目标结点
			
			q->next = p->next; //直接让前驱结点指向目标结点的后续结点
			free(p);//然后释放目标结点
			break;//跳出循环
		} else {
			q = p; //如果目标指针p,的指针域不是目标值
			//q向后移动一个
			p = p->next;
			//p指向p->next,也是向后移动一个
		}
	}
	if (p == NULL) { //也就是说找到最后都,没找到目标结点
		printf("没有符合条件的结点\n");
	}
}

/*
  在链表中插入结点
  
  在链表中插入结点,是一种非常常见的,相对复杂的链表操作
  
  要想在链表中插入一个新结点,首先必须确定插入的位置
  
  
  
  一般来说通过查找第一个符合条件的结点,来确定插入的位置
  
  
  带头结点的单向链表的插入步骤
  1.首先,为新结点分配内存空间,并且存入数据
  2.在链表中查找与插入位置相对应的目标结点
  3.将新结点插入到目标结点之前(或之后).
  
  在目标结点之后插入新结点,相对容易实现,同时也很少使用
  
  所以我们现在只讨论在目标结点之前插入新结点的情况
  
  
  
  例如在一个带头结点的单向动态链表,所有结点按照数据域的值升序排列
  要求传入一个结点使所有的结点仍然按照数据域的值升序排列
  
  
  1.确定新结点的插入位置
  
  新结点应该插入到所有结点值小于它的结点之后,第一个结点值不小于它的结点之前
  
  由于链表的前端开始查找,按照结点值由大到小的顺序进行比较
  
  因此应该将第一个结点值不小于新结点的结点,作为查找的目标结点
  然后在其前面插入新结点。
  
  
  2.如何在目标结点之前插入新结点?
  要让目标结点的前驱结点的指针域指向新结点,另一方面还要让新结点的指针域指向目标结点
  
  由于在单项链表的结点中只有指向后续结点的指针,而没有指向前驱结点的指针
  因此,无法通过目标结点获得其前驱结点的地址
  
  
  所以,需要定义三个指针变量r,p,q,分别指向新结点,目标结点以及前驱结点
 */
void insert(NODE *head,int t)
{
	//插入链表结点函数,head为头指针,t为待插入结点值
	NODE *p,*q,*r;
	r=(NODE*)malloc(sizeof(NODE));//给新结点分配内存
	//3.动态创建一个新结点,并且使得指针r指向它
	//4.将形参传入的正整数存入新结点的数据域中
	//5.使得指针q,p分别指向头结点以及后续结点;
	r->data=t;//存入数据
	
	q=head;
	p=head->next;
	
	while(p!=NULL){
		
	if(p->data<t){//查找目标结点
		q=p;
		p=p->next;
	}
	else
	{
	break;
	}
	}
	q->next=r;
	r->next=p; 
	//6.若p==null,说明新结点的值很大,转向第九步。
	//7.若p所指向的结点的值小于新结点的值,则使得所指向的p所指向的结点
	//使得p指向下一个结点,

//8.否则,在q所指向的结点之间插入新结点:然后返回主调函数


//q->next=r;
//r->next=p;



	//9.在末结点(即q所指向的结点)之后连接新结点.然后返回主调函数
	
	
//q->next=r;
//r->next=p;

	
	
	
return ;
}


int main() {
	NODE *head;
	
	
	head = create();
	print(head);
	int data;
	while(1){
		printf("请输入插入的正整数(以负数结束):");
		scanf("%d",&data);
		if(data<0){
			break;
		}
		
insert(head,data);//插入新结点
print(head);
	}

	
//	int data;
//	while (1) {
//		printf("输入您想要删除的数据(输入负数结束):\n");
//		scanf("%d", &data);
//		if (data < 0) {
//			break;
//		}
//		dele(head, data);
//		print(head);
//	}
	
	
	return 0;
}

链表的销毁

今天在b站听的数据结构网课讲的链表的销毁现在我自己来实现一下

#include <stdio.h>

#include <stdlib.h>

struct node
{
	int data;
	struct node* next;
};
typedef struct node NODE;

NODE *create(int n)
{
NODE *head,*p,*q;
	int t;
	head = (NODE*)malloc(sizeof(NODE));	
	p=head;
	for(int i=0;i<n;i++){
		q=(NODE*)malloc(sizeof(NODE));	
		scanf("%d",&t);
		q->data=t;
		p->next=q;
		p=q;
	}
	p->next=NULL;
	return head;
}
void print(NODE*head)
{
	int t;
	NODE *p;
	p=head->next;
	while(p!=NULL){
		t=p->data;
		printf("%d ",t);
		p=p->next;
	}
	printf("\n");
}
/*
这是一个销毁链表的函数
销毁也就是将链表全部的节点都清空包括头节点
该函数需要链表的头指针
该函数没有返回结果
*/

void destroy(NODE* L)
{
	//在这一个函数中我们让L始终指向p的后续节点
	NODE* p;//定义一个目标指针
	while(L!=NULL){//只要L所指向的地方不为null,继续循环
	p=L;//让目标节点p指向L所指向的节点
	L=L->next;//让L指向p的后续节点,防止链表丢失
	free(p);//释放目标节点
	}
	printf("链表已经销毁成功\n");
	printf("L=%p\n",L);
	printf("p=%p",p);	
}
int main()
{
	int n;
	NODE *head;
	scanf("%d",&n);
	head=create(n);
	print(head);
	destroy(head);

	
	
	return 0;
}

删除链表中的第i个元素



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

struct node
{
	int data;
	
	struct node* next;
};
typedef struct node NODE;

NODE* create()
{
	NODE *head,*q,*p;
	int t;
	head = (NODE*)malloc(sizeof(NODE));
	p=head;
	
	while(1){
		printf("请输入结点元素(输入负数结束)\n");
		scanf("%d",&t);
		if(t==0){
			break;
		}
		else
		{
			q=(NODE*)malloc(sizeof(NODE));
			q->data=t;
			p->next=q;
			p=q;
		}
	}
	
	p->next=NULL;
	
	
	return head;
}

void print(NODE*head)
{
	NODE *p;
	int t;
	p=head->next;
	while(p!=NULL){
		
		t=p->data;
		printf("%d ",t);
		p=p->next;
	}
	printf("\n");
	
}

//NODE* dele(NODE* head,int e)
//{
//	int t;
//	NODE* p,*q;
//	q=head;
//	p=q->next;
//	while(p!=NULL){
//		t=p->data;
//		if(t==e){
//			q->next=p->next;
//			break;
//		}
//q=p;
//p=q->next;
//	}
//	
//	return head;
//	
//	
//	
//}


NODE* dele(NODE* head,int i)
{

NODE *p;//用来指向目标节点的前驱结点
int j=0;//用来找到i-1位置在哪里
NODE *q;//用来指向目标结点并且释放它
p=head;
j=0;
while(p->next!=NULL && j<i-1){//当循环结束的时候,要么p->next==null,要么j==i-1
	p=p->next;//p指针继续向后移动
	j++;//同时j的值加1
}

if(p->next==NULL || j>i-1){//如果p->next==null这时候就说明目标序号超过了链表的长度
//如果j>i-1说明目标序号小于链表的长度
//我们直接退出就好
	printf("输入的目标序号有误\n");
}
else
{
	//如果找到了正确的目标值
	q=p->next;//让指针q指向后续结点,方便一会释放
	
	p->next=q->next;
	//将目标结点的后续结点挂在目标结点的前驱结点的前面
	free(q);//释放目标结点
}
	return head;
	
	
	
}

int main()
{
	NODE* head;
	head=create();
	print(head);
	int e;
	scanf("%d",&e);
	head=dele(head,e);
	print(head);
	
	return 0;
}

头插法建立逆序链表

今天在学校oj上面做的一个题简单的分享一下
使用头插法建立逆序链表


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

struct node {

	int data;
	struct node* next;

};
typedef struct node NODE;

/*
  该函数的目的用来创建链表
  该函数有一个参数就是需要创建的链表的长度
  该函数的返回值为头指针的值
 */
NODE* create(int n) {
	NODE *head, *p; //定义头指针head和目标指针p;
	int t;
	head = (NODE*)malloc(sizeof(NODE)); //分配一个头节点并且让头指针指向头节点
	head->next = NULL; //将头节点的指针域赋值为空指针
	for (int i = 0; i < n; i++) {
		scanf("%d", &t);
		p = (NODE*)malloc(sizeof(NODE)); //分配一个目标节点,并且让p指向它
		p->data = t; //将数据存入目标节点的数据域中
		//下面就是要将目标节点挂到头节点上
		p->next = head->next; //这样把头节点指针域的值赋值给了目标目标节点的指针域
		head->next = p; //然后将头节点指针域的指针指向目标节点,就将元素挂在了上面

		//然后我在纸上演示了挂上第二个节点的过程和第一个没有任何区别,这就是引入头节点的好处吧
	}


	return head;//将头节点返回
}
/*
  该函数的目的用来遍历链表
  该函数有一个参数就是头指针的值
  该函数没有返回值
 */
void print(NODE *head) {//对链表进行遍历
	int count = 0; //这个是用来控制输出格式的我们不用管他
	NODE *p;//定义一个目标指针
	int t;//定义一个临时变量存储数据域的值
	p = head->next;//让目标指针指向首节点
	while (p != NULL) {//只要目标节点不为null,就执行循环
		if (count != 0) {
			printf(" ");
		}
		count++;
		t = p->data;//将目标节点的值赋值给t
		printf("%d", t);//将t的值打印出来
		p = p->next; //让目标指针p向后移动直到null;
	}
}

int main() {
	int n;
	NODE *head;//定义一个指针变量,来接收头指针的值
	scanf("%d", &n);
	head = create(n); //创建链表
	print(head);//遍历链表
	return 0;
}

头插法建立链表


#include <stdio.h>
#include <stdlib.h>
/*
  先建立一个顺序的链表然后用头插法把这个链表逆序
 */
struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

/*
  创建一个链表以负数结束
 */
NODE* creat() {
	int t;
	NODE* head, *q, *p;//三个指针变量,分别是头指针head,临时指针q,尾指针p
	head = (NODE*)malloc(sizeof(NODE));
	p = head;// 让尾指针也指向头节点
	
	while (1) {
		scanf("%d", &t);
		if (t == -1) {
			break;
		}
		q = (NODE*)malloc(sizeof(NODE));
		q->data = t;//给目标节点的数据域赋值
		p->next = q;// 将目标节点挂在其前驱节点之后
		p = q;//更新尾指针
	}
	q->next=NULL;//给最后一个节点的指针域赋值为null
	
	
	return head;// 返回头节点
}

//用该函数对链表进行遍历
void print(NODE *head)
{
	int count=0;
	int t;
	NODE *p;
	p=head->next;
	
	while(p!=NULL){
		if(count!=0){
			printf(" ");
		}
		count++;
		t=p->data;
		printf("%d",t);
		p=p->next;
	}
	
}

/*
  该函数为链表逆置的函数
  该函数需要的
  
  
  
 */
void reverse(NODE *head)
{
	NODE *p,*q;//用p来指向目标节点,让q来保存目标节点的后续节点
	// 防止后续节点的丢失
	//1.将头节点切断,并且让q指向首节点
	p=head->next;//让q指向首节点
	head->next=NULL;//将头结点的指针域赋值为null
	while(p!=NULL){
		q=p->next;//用一个指针q来保存目标节点的后续节点
		p->next=head->next;//让头节点指针域的指针值赋值给目标节点的指针域
		head->next=p;//让头节点指向目标节点
		p=q;//将目标节点向前移动
		
		//通过循环这些代码,可以将链表元素全部逆置
	}
	
	
	
	
	
	
}

int main() {
	NODE *head;//定义一个指针变量用来储存头节点
	head=creat();//将创建好的链表的头节点赋值给head
	//print(head);
	//printf("\n");
	reverse(head);//调用链表逆转函数
	print(head);//遍历链表
	
	
	return 0;
}

顺序建立链表


这是我在学习的oj上面做的第一个链表的题目简单分享一下


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

struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

NODE* create(int n) {
	int t;//定义临时储存数据的变量t;
	NODE *head, *p, *q;//定义头指针,尾指针,和储存临时变量的指针
	head = (NODE*)malloc(sizeof(NODE));//动态分配一块内存,并且让头指针指向它。这就是头结点的地址;
	p = head;//让末尾指针也指向头结点。当然我们一会会移动末尾指针
	
for(int i=0;i<n;i++){
scanf("%d",&t);
q=(NODE*)malloc(sizeof(NODE));//动态分配一块内存并且让q指向它
q->data=t;//将搜集到的t赋值给q指针所指向的数据域;
p->next=q;//如果是第一次会将首结点挂在头结点上面
p=q;	//这里将q的值赋值给p,就是让p指向最后一个结点
}	
p->next=NULL;//循环结束将最后一个结点的指针域赋值为null

return head;//将头指针返回
}

void print(NODE *head)//链表的遍历
{
int a=0;
	NODE *p=head->next;//定义p,让p指向head->next;也就是p存放了首结点的地址
	while(p!=NULL){//只要p的值不为null,进行循环
		if(a!=0){
			printf(" ");
		}
		a++;
		printf("%d",p->data);//打印出p所指向的那个data
		p=p->next;//然后将p指针后移
	}
printf("\n");
}



int main() {

int n;
scanf("%d",&n);
NODE *p=create(n);
print(p);







	return 0;
}

数据结构实验之链表五:单链表的拆分

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

struct node
{
	int data;
	struct node* next;
};

typedef node NODE;

NODE* create(int n)
{
	int t;
	NODE* head,*q,*p;
	head=(NODE*)malloc(sizeof(NODE));
	p=head;
	for(int i=0;i<n;i++){
		scanf("%d",&t);
		
		q=(NODE*)malloc(sizeof(NODE));
		q->data=t;
		p->next=q;
		p=q;
	}
	p->next=NULL;
	return head;
}//创建一个单链表


/*
改函数是将节点中的值为偶数的节点拿出来并且建立一个新链表
改函数需要原链表的头指针
改链表将返回新链表的头指针
*/
NODE* chaifen1(NODE* head,int* a)
{
	NODE* T1;//新链表的头指针
	NODE* Tp;//一直指向新链表的尾节点
	NODE* Tq;//指向新分配的节点
	T1=(NODE*)malloc(sizeof(NODE));//为新节点分配一个头节点
	Tp=T1;//尾指针指向尾节点
	int count=0;
	NODE *p;//用指向传入链表的指针
	p=head->next;
while(p!=NULL){//如果原链表不为空就执行循环
	if(p->data%2==0){//如果该节点的数据域为偶数
		Tq=(NODE*)malloc(sizeof(NODE));//动态分配一个新节点
		Tq->data=p->data;//给新节点的数据域赋值
		count++;//计数器加1
		Tp->next=Tq;//将新节点挂在新链表上面
		Tp=Tq;//移动新链表的尾指针
	}
	p=p->next;//移动用来遍历原链表的指针
}
	Tp->next=NULL;//给新链表的尾节点的指针域赋值为null
	*a=count;//将原链表有多少个偶数传回
	return T1;//返回新链表的头指针
}


//这个和上面的函数相同只不过是用来计算奇数的
NODE* chaifen2(NODE* head,int* b)
{
	NODE* T2;
	NODE* Tp;
	NODE* Tq;
	T2=(NODE*)malloc(sizeof(NODE));
	Tp=T2;
	int count=0;
	NODE *p;
	p=head->next;
while(p!=NULL){
	if((p->data)%2!=0){
		Tq=(NODE*)malloc(sizeof(NODE));
		Tq->data=p->data;
		count++;
		Tp->next=Tq;
		Tp=Tq;
	}
	p=p->next;
}
	Tp->next=NULL;
	*b=count;
	return T2;
}
/*
这是一个用来遍历链表的函数
*/
void print(NODE* head)
{
	int t;
	NODE* p;
	p=head->next;
	while(p!=NULL){
		t=p->data;
		printf("%d ",t);
		p=p->next;
	}
	
printf("\n");	
}


int main()
{
	NODE* head;
	int a,b;
	NODE* T1,*T2;
int n;
scanf("%d",&n);
head=create(n);
T1=chaifen1(head,&a);
T2=chaifen2(head,&b);

printf("%d %d\n",a,b);
print(T1);
print(T2);
	return 0;
}

有序链表的归并


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

struct node {
	int data;
	struct node* next;
};
typedef struct node NODE;

NODE *create(int n) {
	int t;
	NODE *head, *p, *q;
	head = (NODE*)malloc(sizeof(NODE));
	p = head;

	for (int i = 0; i < n; i++) {
		q = (NODE*)malloc(sizeof(NODE));
		scanf("%d", &t);
		q->data = t;
		p->next = q;
		p = q;
	}
	q->next = NULL;
	return head;
}

void print(NODE*head) {
	int count = 0;
	int t;
	NODE *p;
	p = head->next;
	while (p != NULL) {
		if (count != 0) {
			printf(" ");
		}
		count++;
		t = p->data;
		printf("%d", t);
		p = p->next;
	}
//	printf("\n");

}
/*
该函数为归并有序链表的函数
该函数需要两个参数分别是两个链表的头指针
该函数将返回一个归并好了的有效链表的头指针
*/
NODE *merger(NODE* head1, NODE* head2) {
	NODE *head3, *p1, *p2, *p3;
	/*
	这里定义了4个指针变量
	指针head3为归并完成后链表的头指针
	指针p1用来遍历第一个链表
	指针p2用来遍历第二个链表
	指针p3一直用来指向新生产链表的尾节点;
	*/

	head3 = (NODE*)malloc(sizeof(NODE));
	/*
	为新链表分配一个头节点,并且让头指针head3指向该节点
	*/
	p3 = head3;//让尾指针p3也指向头节点
	p1 = head1->next;//让指针p1指向链表1的首节点
	p2 = head2->next;//让指针p2指向链表2的首节点

	while (p1 != NULL && p2 != NULL) {
		//只要两链表都不为空就执行循环
		if ((p1->data) < (p2->data)) {
			p3->next = p1;//将p1所指向的节点挂在p3指向的节点的后面
			p1 = p1->next;//p1指针向前移动
			p3 = p3->next;//尾指针p3向前移动
		} else {
			p3->next = p2;//将p2所指向的节点挂在p3所指向的节点的后面
			p2 = p2->next;//p2指针向前移动
			p3 = p3->next;//尾指针p3向前移动
		}

	}
	if (p1 == NULL) {
		p3->next = p2;
		/*
		如果最后链表1先空
		将链表2剩下的节点全部挂到新链表上面
		*/
	} else {
		/*
			如果最后链表2先空
			将链表2剩下的节点全部挂到新链表上面
			*/
		p3->next = p1;
	}
	return head3;//返回新生成的链表的头指针

}



int main() {
	NODE *head1, *head2, *head3;
	int m, n;
	scanf("%d %d", &m, &n);
	head1 = create(m);
	head2 = create(n);
//	print(head1);
//	print(head2);
	head3 = merger(head1, head2);
	print(head3);
	return 0;
}

现在是2022.12.05今天又再pta上面做了一个类似的题目
再将代码简单的保存一下


下面是这个归并链表的函数代码

List Merge( List L1, List L2 ) {

	List L3, p3, p1, p2;
	L3 = (struct Node*)malloc(sizeof(struct Node));
	p3 = L3; //p3始终指向新链表的末尾
	p1 = L1->Next; //用p1指向L1链表
	p2 = L2->Next; //用p2指向L2链表

	while (p1 != NULL && p2 != NULL) { //当两个链表都不为空时开始循环
		if (p1->Data < p2->Data) { //如果p1->data比较小
			p3->Next = p1; //让p3指向p1
			p3 = p1; //将p3移动到尾节点位置
			p1 = p1->Next; //让p1指向下一个结点位置
		} else { //当p2->data比较小的时候和上面相同只不过是操作的p2
			p3->Next = p2;
			p3 = p2;
			p2 = p2->Next;
		}
	}
	if (p1 == NULL) {
		p3->Next = p2; //当p1为空的时候,将p2全部挂到p3上面
	} else {
		p3->Next = p1; //当p2为空的时候,将p1全部挂在p3上面
	}
	L1->Next = NULL; //将l1链表清空
	L2->Next = NULL; //将l2链表清空
	return L3;//返回新链表的头指针
}

约瑟夫问题


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

struct node {
	int data;
	struct node* next;


};

typedef struct node NODE;

/*
该函数的目的是建立一个数据域的值为从1—n链表
该函数需要输入一个n
该函数的返回值是一个头指针
*/
NODE* create(int n) {
	
	NODE* head, *q, *p;
	head = (NODE*)malloc(sizeof(NODE));
	head->data = 0;
	p = head;

	for (int i = 1; i <= n; i++) {
		q = (NODE*)malloc(sizeof(NODE));
		q->data = i;
		p->next = q;
		p = q;
	}
	p->next = head->next;//这里有点普通的循环链表有点不一样
	//这里的尾指针指向首元节点,普通的循环链表都是头结点
	return head;//返回头指针
}

void print(NODE* head) {
	NODE* p;
	p = head->next;
	do {
		printf("%d ", p->data);
		p = p->next;
	} while (p->data != 1);

}

/*
这是一个计算循环链表长度的函数
需要该链表中的任意一个结点的地址
该函数的返回值是该链表的长度
*/
int length(NODE* p) {
	NODE* temp;
	temp = p;//将p储存的地址赋值给temp;因为我们后面要用到
	//这个最初传入的地址
	int len = 0;
	//这里使用do while循环因为循环至少要进行一次
	do {
		p = p->next;
		len++;

	} while (p != temp);
	return len;//返回该链表的长度
}

NODE* dele(NODE* p, int m) {
	NODE* q;//定义一个q变量,目的是让他指向p的后续结点
	int j = 1;
	while (j != m - 1) {
		p = p->next;
		j++;
	}//这个循环是移动p让p指向目标结点的前驱结点
	q = p->next;//让q指向目标结点
	p->next = q->next;//把目标结点的next域的值赋值给p指向next的值
	free(q);//释放目标结点的值
	return p->next;//这里要返回p->next的值,因为下一次计数要从
	//目标结点的后续结点开始
}





int main() {
	int n;
	int m;
	scanf("%d", &n);
scanf("%d",&m);

	NODE* head;
	head = create(n);//创建一个带头结点的链表
//	print(head);

NODE* p;//定义一个p指针
p=head->next;//让p指针指向首元结点
while(length(p)!=1){//当链表的长度为1的时候退出循环
	p=dele(p,m);//每次删除第m给结点
}
//这时最后链表只剩下一个结点
printf("%d",p->data);//打印出最后剩下的一个结点的值





	return 0;
}

在第i个元素之前插入结点

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

struct node
{
	int data;
	struct node* next;
};
typedef struct node NODE;

NODE* create()
{
NODE* head,*q,*p;
int t;
head = (NODE*)malloc(sizeof(NODE));
p=head;

while(1){
	scanf("%d",&t);
	if(t==0){
		break;
	}
	else
	{
		q=(NODE*)malloc(sizeof(NODE));
		q->data=t;
		p->next=q;
		p=q;
	}
}	
	p->next=NULL;
	
	return head;
	
	
}

void print(NODE* head)
{
	NODE *p;
	int t;
	p=head->next;
	while(p!=NULL){
		t=p->data;
		printf("%d ",t);
		p=p->next;
	}
}
/*
该函数是链表的插入算法
该函数有3个参数头指针head,插入位置i,插入数值e
该函数的返回值为一个头指针
*/
NODE* insert(NODE* head,int i,int e)
{
	
	NODE* p,*s;//定义两个指针变量p,s;
	p=head;//让p也指向头节点
	int j=0;//让j初始化为0
	while(p!=NULL && j<i-1){
		p=p->next;
		j++;
	}//寻找目标结点的前驱结点
	if(p==NULL || j>i-1){//如果p满足这两个条件的其中之一
	//说明给出的i值的信息有误
		printf("给出的i值有误\n");
	}
	else
	{
		//动态分配一个新结点并且让s指针指向这个结点
		s=(NODE*)malloc(sizeof(NODE));
		s->data=e;//给目标结点的数据域赋值
		s->next=p->next;//让新生成的结点的指针域指向下一个结点
		p->next=s;//让目标结点指向新生成的结点
	}
	
	
	
	return head;
}


int main()
{
	NODE*head;
	int i;
	int e;
	head=create();
	print(head);
	printf("\n请输入要插入的位置\n");
	scanf("%d",&i);
	printf("请输入要插入的值\n");
	scanf("%d",&e);
	head=insert(head,i,e);
	print(head);
	
	
	
	
	return 0;
}

递增的整数序列链表的插入

递增的整数序列链表的插入

数据结构(浙大版)的一个课后习题,分享一下


List Insert( List L, int X ) {
	PtrToNode p, q, s;
	/*
	p用来指向目标结点的前驱
	q用来指向目标结点
	s用来指向新生成的结点
	这里的目标结点就是第一个比X大的数
	*/
	p = L;//让p指向头结点
	q = L->Next; //让q指向首元结点

	while (q != NULL) {//对链表进行遍历操作
		if (q->Data < X) {//如果当前的元素比目标元素小
			p = q;//让p向后移动一位
			q = q->Next;//让q也向后移动一位
			//但是要保证p始终指向q的前驱
		} else {
			//如果当前的元素比目标元素大
			//直接跳出循环
			break;
		}
	}

//我又画图讨论了一下,最后添加新结点不需要分类讨论
	//如果循环是直接跳出的那么p,q已经指向了我们需要操作的结点
		s = (struct Node*)malloc(sizeof(struct Node));//动态分配一个新的结点,并且让s指向这个结点
		s->Data = X;//给数据域赋值
		s->Next = q;//将后半段的链表直接挂在s上面
		p->Next = s;//将带着s的后半段链表直接挂在p的后面
	return L;//返回头指针
}


单链表中重复元素的删除

单链表中重复元素的删除



这个问题考察的知识还是很全面的,做这个问题,需要用到知道

  1. 如何用头插法建立单链表.
    2.如果遍历整个链表的元素
    3.如何计算整个链表中的长度
    4.如何在单链表中删除指定元素
#include <stdio.h>
#include <stdlib.h>

struct node {
	int data;
	struct node* next;
};

typedef struct node NODE;


/*
该函数为单链表创建函数
该函数需要一个参数n,表示有几个节点
该函数将返回一个头指针
根据题目要求这里是用头插法建立的链表

*/
NODE* create(int n) {
	int e;
	NODE *head, *q;
	head = (NODE*)malloc(sizeof(NODE));
	head->next = NULL;
	for (int i = 0; i < n; i++) {
		scanf("%d", &e);
		q = (NODE*)malloc(sizeof(NODE));
		q->data = e;
		q->next = head->next;
		head->next = q;
	}

	return head;
}
/*
该函数为遍历字符串的函数
*/
void print(NODE* head) {
	int t;
	NODE* p;
	p = head->next;
	while (p != NULL) {
		t = p->data;
		printf("%d ", t);
		p = p->next;
	}
	printf("\n");

}
/*
该函数为删除链表中从复元素的函数
该函数需要头指针head
该函数没有返回值
*/
void deletesame(NODE* head) {
	int e;
	NODE *p, *q, *s;
	/*
	这里我们用双重循环来查找重复的元素
	用p作为外层循环的指针
	s用来始终指向目标节点的前驱节点
	q用来指向目标节点
	*/
	p = head->next;//让p指向头节点

	while (p != NULL) {//注意这里的外层循环不能用长度n来控制因为循环
		//里面会删除指定元素的,导致链表的长度变化
		e = p->data;//将p所指向的数据域保存下来
		s = p;//让s和q相等
		q = s->next;//q指向s的后续节点,因为我们要找到目标节点的前驱节点
		while (q != NULL) {//用循环的形式遍历整个链表
			if (e == q->data) {//如果找到目标结点
				s->next = q->next;//让目标结点前驱结点指向目标结点的后续结点
				free(q);//释放目标结点
				q = s->next;//移动指针让其指向下一个结点

			} else {
				s = q;
				q = q->next;
				//如果没找到就继续后移动
				//但还是要让s始终指向p的前驱
			}
		}
		p = p->next;//不要忘了外层循环每次向后移动
	}
}
/*
该函数为计算链表长度的函数
*/
int length(NODE* head) {
	int len = 0;
	NODE* p;
	p = head->next;
	while (p != NULL) {
		len++;
		p = p->next;
	}



	return len;
}

int main() {
	int n;
	scanf("%d", &n);
	NODE* head;
	head = create(n);
	printf("%d\n", length(head));
	print(head);

	deletesame(head);
	printf("%d\n", length(head));
	print(head);

	return 0;
}

标签:NODE,表示,结点,实现,head,next,链表,指针
From: https://www.cnblogs.com/harper886/p/17690988.html

相关文章

  • 如何让Android平台像网络摄像机一样实现GB28181前端设备接入?
     技术背景好多开发者在做国标对接的时候,首先想到的是IPC(网络摄像头),通过参数化配置,接入到国标平台,实现媒体数据的按需查看等操作。像执法记录仪等智能终端,跑在Android平台,对接GB28181平台的需求也非常大,网上相关demo也不少,但真正设计符合相关协议规范、功能完善、长时间稳定运......
  • 机器学习算法原理实现——决策树里根据信息增益选择特征
    先说熵的定义:  再看信息增益信息增益是一种用于特征选择的指标,用于衡量特征对于数据集分类的贡献程度。它基于信息熵的概念,通过比较特征划分前后的信息熵差异来评估特征的重要性。信息熵是衡量数据集纯度的指标,表示数据集中的不确定性或混乱程度。信息熵越高,数据集的不确......
  • 基于微信小程序的停车场设计与实现
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了停车场微信小程序的开发全过程。通过分析停车场微信小程序管理的不足,创建了一个计算机管理停车场微信小程序的方案。文章介绍了停车场微信小程序的系统分析部分,包括可行性分析等,系统设......
  • MyBatis实现In查询(XTHS 实测)
    一. SQL语法实现In查询SQL语句实现In查询SELECT*FROMuser_infoWHEREuser_namein('xixi','haha');二. MyBatis实现In查询错误范例:如果在MyBatis中也使用类似SQL语法来实现In查询,像如下示例,肯定会报错,因为MyBatis不支持这样的写法。//Dao层List<UserInf......
  • 合并链表
    例2.3有两个链表LA和LB,其元素均为非递减有序排列,编写算法,将它们合并成一个链表LC,要求LC也是非递减有序排列。例如,LA=(2,2,3),LB=(1,3,3,4),则LC=(1,2,2,3,3,3,4)。#include<stdio.h>#include<stdlib.h>#defineMAX100typedefstructNode{intnum;structN......
  • vue前端table列表右侧的滑动条怎样实现
    要在Vue前端table列表右侧添加滑动条,您可以使用CSSoverflow属性和::-webkit-scrollbar伪元素来实现。以下是示例代码:<template><divclass="table-container"><tableclass="table"><!--表头--><thead><tr>......
  • python实现自己的全局热键的第2种方法
    之前有过一版python实现的全局热键,但是在实际运行中发现,有时候不太灵敏,明明按下了目标热键,为什么没有反应呢?通过定位发现,有时候键盘勾子捕获不到ctrldown消息,特别是一段时间不操作电脑后容易出现这种情况,这时候ctrl键确实处于按下的状态(通过GetKeyState函数可以......
  • 代码随想录算法训练营第四天| 24. 两两交换链表中的节点, 19.删除链表的倒数第N个结点
    24.两两交换链表中的节点mydemo(超时)/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val(0),next(nullptr){}*ListNode(intx):val(x),next(nullptr){}*ListNode(intx,Lis......
  • 1782_Adobe Reader X实现pdf分页保存
    全部学习汇总:GitHub-GreyZhang/windows_skills:someskillswhenusingwindowssystem.看了一本pdf电子书,觉得其中几页很值得分享。如果分享整本书当然是不错的选择,但是分享整本书很可能会导致一个结局——内容太多别人不会去看!这样想来,分页导出需要分享的部分再进行分享就好......
  • 1777_树莓派截图功能实现
    全部学习汇总:GitHub-GreyZhang/little_bits_of_raspberry_pi:myhackingtripaboutraspberrypi.        最近入手了树莓派的3B版本,安装了官方推荐的Debian版本。之前使用Linux的几个发行版本的时候,系统中通常会有KDE等集成的截图工具,使用十分方便。在树莓派定制的......