数据结构--第二天

--链表

        -链表的概念

           线性表的链式存储结构,我们叫做链表,将线性表L=(a0,a1,...an-1)中各元素分布在储存器中的不同存储区域,线性表中的各元素称为结点,通过地址或指针建立节点之间的联系所得到的存储结构叫做链表结构

        -数据域和指针域

           数据域:节点的data域存放数据元素a0

           指针域:指针域是一个指针,指向a0的直接后继节点

        -头节点、尾节点和虚拟头节点

           头节点:链表中的第一个节点叫做头节点

           尾节点:链表中的最后一个节点叫尾节点(尾节点的指针域为NULL

           虚拟头节点:为了方便对链表进行操作,一般会在链表的头节点前面,再创建一个节点,称为虚拟头节点dummyhead),让该节点的指针域指向真正的头节点,(虚拟头节点的数据域默认不使用,只是用指针域

           封装节点的代码实现:

-单向链表的代码实现

        linked_list.c
#include "linkedlist.h"

void linkedlist_init(node_t** p_head){                                         
        node_t* p_node = (node_t*)malloc(sizeof(node_t));        
        if(p_node==NULL){                                        
                printf("malloc failure:%s\n",strerror(errno));   
                return;                                    
        }                                                        
        memset(p_node,0,sizeof(node_t));                                                              
        p_node->next = NULL; 
	*p_head = p_node;	
}

// 添加的方法
bool linkedlist_insert_head(node_t* p_head,datatype_t val){
	//将data添加到链表的头部
	// 1、封装成节点
	node_t* p_node = (node_t*)malloc(sizeof(node_t));
	if(p_node==NULL){
		printf("malloc failure:%s\n",strerror(errno));
		return false;
	}
	memset(p_node,0,sizeof(node_t));
	p_node->data = val;
	p_node->next = NULL;
	// 2、改变指针的指向
	p_node->next = p_head->next;
	p_head->next = p_node;
	return true;
}

// 打印链表中所有的结点数据
void linkedlist_display(node_t* head){
	node_t* cur = head->next;
	while(cur!=NULL){
		printf("%d--->",cur->data);
		cur= cur->next;
	}
	printf("NULL\n");
}


bool linkedlist_insert_tail(node_t* p_head,datatype_t val){
	 // 1、封装成节点
        node_t* p_node = (node_t*)malloc(sizeof(node_t));
        if(p_node==NULL){
                printf("malloc failure:%s\n",strerror(errno));
                return false;
        }
        memset(p_node,0,sizeof(node_t));
        p_node->data = val;
        p_node->next = NULL;

	// 找尾巴
	node_t* tail=p_head;
	while(tail->next!=NULL){
		tail = tail->next;
	}
	tail->next = p_node;
	return true;
}

bool linkedlist_insert_order(node_t* p_head,datatype_t val){
         // 1、封装成节点
        node_t* p_node = (node_t*)malloc(sizeof(node_t));
        if(p_node==NULL){
                printf("malloc failure:%s\n",strerror(errno));
                return false;
        }
        memset(p_node,0,sizeof(node_t));
        p_node->data = val;
        p_node->next = NULL;

	// 找添加结点的前驱结点
	node_t* pre=p_head;
	while(pre->next!=NULL && pre->next->data < val){
		pre=pre->next;
	}
	p_node->next = pre->next;
	pre->next = p_node;
        
	return true;
}

// 删除节点根据值
bool linkedlist_remove_data(node_t* head,datatype_t data){
	node_t* pre = head;
	while(pre->next!=NULL && pre->next->data !=data){
		pre=pre->next;
	}
	if(pre->next ==NULL){
		printf("没有找到要删除的节点\n");
		return false;
	}else{
		// 保存删除节点
		node_t* delnode = pre->next;
		pre->next = pre->next->next;
		free(delnode);
		delnode=NULL;
		return true;	
	}
}

void linkdelist_clean(node_t** head){
	if(*head == NULL){
                return;
        }

	node_t* pre = *head;
	while(pre->next!=NULL){
		node_t* delnode = pre->next;
		pre->next = pre->next->next;
		free(delnode);
		delnode=NULL;
	}
	free(*head);
	*head= NULL;
}
        linked_list.h
#ifndef __HEAD_LINKED_LIST_H__
#define __HEAD_LINKED_LIST_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>

typedef int datatype_t;

//  定义结构体类型
typedef struct Node{
        // 数据域
        datatype_t data;
        // 指针域
        struct Node* next;
}node_t;

extern bool linkedlist_insert_head(node_t* p_head,datatype_t val);
extern void linkedlist_display(node_t* head);
extern bool linkedlist_insert_tail(node_t* p_head,datatype_t val);
extern bool linkedlist_insert_order(node_t* p_head,datatype_t val);
extern void linkedlist_init(node_t** p_head);
extern bool linkedlist_remove_data(node_t* head,datatype_t data);
extern void linkdelist_clean(node_t** head);
#endif

main.c
#include "linkedlist.h"

void menu();
void insert_head_data(node_t* p_head);
void insert_tail_data(node_t* p_head);
void insert_order_data(node_t* p_head);
void remove_data(node_t* head);
int main(){
	node_t* head = NULL;
	int select;
	do{
		menu();
		printf("请选择:");
		scanf("%d",&select);
		// 针对不同的选择进行不同的操作
		switch(select){
			case 1:
				linkedlist_init(&head);
				break;
			case 2:
				if(head==NULL){
					linkedlist_init(&head);
				}
				insert_head_data(head);
				break;
			case 3:
				if(head==NULL){
                                        linkedlist_init(&head);
                                }
				insert_tail_data(head);
				break;
			case 4:
				if(head==NULL){
                                        linkedlist_init(&head);
                                }
				insert_order_data(head);
				break;
			case 5:
				if(head==NULL){
					linkedlist_init(&head);
				}
				remove_data(head);
				break;
			case 8:
				linkedlist_display(head);
				break;
			case 0:
				printf("welcome to next come\n");
				linkdelist_clean(&head);
				exit(EXIT_SUCCESS);
				break;
			default:
				printf("选择错误\n");
		}
		
	}while(1);
}

void menu(){
	printf("-----------链表的操作-----------\n");
	printf("1、初始化链表\n");
	printf("2、在表头添加节点\n");
	printf("3、在尾部添加节点\n");
	printf("4、按顺序添加节点\n");
	printf("5、删除节点\n");
	printf("8、显示链表节点数据\n");
	printf("0、退出\n");
	printf("--------------end---------------\n");
}


void insert_head_data(node_t* p_head){
	printf("请输入要添加的内容:");
	datatype_t num;
	scanf("%d",&num);
	// 调用链表的头插法,将num插入到链表中
	bool result = linkedlist_insert_head(p_head,num);
	if(result){
		printf("插入成功\n");
	}else {
		printf("插入失败\n");
	}	
}

void insert_tail_data(node_t* p_head){
        printf("请输入要添加的内容:");
        datatype_t num;
        scanf("%d",&num);
        // 调用链表的头插法,将num插入到链表中
        bool result = linkedlist_insert_tail(p_head,num);
        if(result){
                printf("插入成功\n");
        }else {
                printf("插入失败\n");
        }
}

void insert_order_data(node_t* p_head){
	printf("请输入要添加的内容:");
        datatype_t num;
        scanf("%d",&num);
        bool result = linkedlist_insert_order(p_head,num);
        if(result){
                printf("插入成功\n");
        }else {
                printf("插入失败\n");
        }

}
void remove_data(node_t* head){
	printf("请输入要删除的内容:");
        datatype_t num;
        scanf("%d",&num);
	bool result = linkedlist_remove_data(head,num);
	if(result){
                printf("删除成功\n");
        }else {
                printf("删除失败\n");
        }
	linkedlist_display(head);
}

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值