C/C++ 语言练习之手撕单链表

c语言实现单链表的一些基本操作

#include<stdio.h>
#include<stdlib.h>
#include <stdbool.h>
//定义链表结构体
typedef struct  Node
{
    int data; //数据
    struct  Node *next; //指向下一个节点的指针
} Node;

//创建并初始化链表
Node *createLinkedList(){
    return NULL; //返回空链表
}

//插入节点到链表开头
Node *insertAtBeginning(Node *head, int data){
    //创建新节点
    Node *newNode = (Node*)malloc(sizeof(Node));
    //设置节点数据
    newNode->data = data;
    //将新节点指向原来的头节点
    newNode->next = head;
    //返回新的链表头节点
    return newNode;
}

//插入节点到链表末尾
Node *insertAtEnd(Node *head, int data){
    //创建新节点
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    //将新节点的下一个节点指针设置为NULL
    newNode->next = NULL;
    //如果链表为空,将新节点作为链表的唯一节点
    if(head == NULL){
        return newNode;
    }
    Node* current = head;

    //遍历链表直到达到最后一个节点
    while(current->next!=NULL){
        current = current->next;
    }
    //将新节点插入到已有链表的末尾
    current->next = newNode;
    //返回原来的头节点
    return head;
}

//在指定的位置插入节点
Node *insertAtPosition(Node* head, int data, int position){
    //创建新的节点
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    //如果插入位置为0,则将新节点作为头节点
    if(position==0){
        newNode->next = head;
        return newNode;
    }
    Node* current = head;
    //找到插入位置的前一个节点
    for(int i =0;i<position-1;i++){
        if(current == NULL){
            printf("位置超出链表存储范围。 \n");
            return head;
        }
        current = current->next;
    }
    //将新节点的next指针指向当前位置的节点
    newNode->next = current->next;
    //将当前位置节点指向新节点
    current->next = newNode;
    //返回原来的头节点
    return head;
}

//从链表开头删除节点

Node *deleteAtBeginning(Node* head){
    if(head==NULL){
        printf("链表为空\n");
        return NULL;
    }
    Node* temp = head;
    //更新头节点
    head = head->next;
    //释放删除节点的内存
    free(temp);
    //返回新的头节点
    return head;
}

//从链表末尾删除节点
Node *deleteAtEnd(Node* head){
    if(head == NULL){
        printf("链表为空!!!\n");
        return NULL;
    }
    //如果有一个节点,直接删除
    if(head->next == NULL){
        free(head);
        return NULL;
    }
    Node* current = head, *prev;
    //找到倒数第二节点
    while(current->next !=NULL){
        prev = current;
        current = current->next;
    }
    //将倒数第二节点的necx指针设置为NULL,删除最后一个节点
    prev->next = NULL;
    //释放节点内存
    free(current);
    //返回原来的头节点
    return head;

}

//根据数据值删除节点
Node *deleteByValue(Node *head, int data){
    if(head == NULL){
        printf("链表为空!!!\n");
        return NULL;
    }
    Node *current = head, *prev;
    //遍历链表找到要删除的节点
    while(current !=NULL&&current->data != data){
        prev = current;
        current = current->next;
    }
    if(current == NULL){
        printf("数据不存在!!!\n");
        return head;
    }
    if(current==head){
        //如果删除节点是头节点,则更新头节点
        head = head->next;
    }else{
        //将前一个节点的next指针跳过删除节点
        prev->next = current->next;
    }
    free(current);//释放节点内存
    return head;
}

//打印链表数据
void printList(Node *head){
    Node* current = head;
    printf("链表所有数据:");
    //表头为空,结束循环
    while(current!=NULL){
        printf("%d  ",current->data);
        current = current->next;
    }
    printf("\n");
}

//主函数 
int main() {
	//创建链表 
    Node* head = createLinkedList();
    printf("链表已经创建完成,可以正常使用!!!\n");
	while(1){
		printf("1、添加新的数据到链表头。\n"); 
		printf("2、添加新的数据到链表尾。\n");
		printf("3、添加新的数据到固定位置。\n");
		printf("4、删除链表头的数据。\n");
		printf("5、删除链表尾的数据。\n");
		printf("6、删除指定数据。\n");
		printf("7、退出程序。\n");
		printf("请输入你的选择:");
		int ch;
		bool flag=false;
		scanf("%d",&ch);
		system("cls");
		switch(ch){
			case 1:{
				int insertN;
				printf("请输入需要插入的数据:");
				scanf("%d",&insertN); 
				head = insertAtBeginning(head, insertN);
				break;
            }
			case 2:{
				int insertEndN;
				printf("请输入需要插入的数据:");
				scanf("%d",&insertEndN);
				head = insertAtEnd(head, insertEndN);
				break;
            }
			case 3:{
				int insertPosN,pos;
				printf("请输入需要插入的数据和位置:");
				scanf("%d %d",&insertPosN,&pos);
				head = insertAtPosition(head, insertPosN, pos-1);
				break;
            }
			case 4:{
				head = deleteAtBeginning(head);
				break;
            }
			case 5:{
				head = deleteAtEnd(head);
				break;
            }
			case 6:{
				int delN;
				printf("请输入需要删除的数据:");
				scanf("%d",&delN); 
				head = deleteByValue(head, delN);
				break;
            }
			case 7:{
            printf("程序结束,欢迎使用。\n");exit(0);
            }
			default:{
				printf("您的输入有误,请检查后重新输入!\n");
				flag=true;
				break;
            }
		}
		if(!flag){
			printf("****-----------------------------****\n");
			printList(head);
			printf("****-----------------------------****\n\n");
		}
		getchar();
	}
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值