c语言单链表的基本操作(代码)

c语言实现单链表的基本操作:建立、打印、删除、插入、逆序。仅供学习之用还需不断完善,有待读者自己研究

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


typedef struct stu
{
	int data; //数据
	struct stu *next; //指向下一节点的指针
}node;

node *creat(int n)//创建链表
{
    node *head,*p1,*p2;
    int i;
    head=p1=p2=(node *)malloc(sizeof(node));//创建节点
    for(i=0;i<n;i++)//利用for语句实现节点数目限制
    {
        if(p2->next!=NULL)
        {
			scanf("%d",&p1->data);
			p2->next=p1;//p2->next保存p1,p2指向最后一个节点
			p2=p1;
			p1=(node *)malloc(sizeof(node));//创建下一个节点
        }
    }
    p2->next=NULL;
    return head;
}

void print(node *head)//打印链表
{
    node *p=head;
    while(p!=NULL)//节点不为空
    {
        printf("%d\n",p->data);//输出节点
        p=p->next;//指向下一个节点
    }
}

node *search(node *head,int data)//查找数据
{
    node *p=head;
    for(;p!=NULL;p=p->next)//遍历整个链表
    {
        if(data==p->data)//对比数据
        printf("%3d,%3d\n",p,p->data);//输出地址和数据
    }
}

node *insert(node *head,int n)//节点插入
{
	int n_1=1;
	node *p1=head,*p2;
	node *s=(node *)malloc(sizeof(node));//创建新节点
	printf("输入插入的数据:");
	scanf("%d",&s->data);
	while(n_1!=n)//对比节点
	{
		p2=p1;//p2保存p1位置
		p1=p1->next;//p1后移
		n_1++;//节点计数
	}
	if(n_1==n)
	{
		if(head==p1)//表头
		{
            s->next=head;//修改head和新节点指针关系
            head=s;
		}
		else//表间
		{
            s->next=p1;//修改新节点和p1,p2的指针关系
            p2->next=s;
		}
	}
	return head;
}

/*node *insert(node *head,int data)
{
	node *p1=head,*p2;
	node *s=(node *)malloc(sizeof(node));//创建新节点
	printf("输入插入的数据:");
	scanf("%d",&s->data);
	while(p1->data!=data)//对比数据域
	{
		p2=p1;//p2保存p1位置
		p1=p1->next;//p1后移
	}
	if(p1->data=data)
	{
		if(head==p1)//表头
		{
            s->next=head;//修改head和新节点指针关系
            head=s;
		}
		else//表间
		{
            s->next=p1;//修改新节点和p1,p2的指针关系
            p2->next=s;
		}

	}
	return head;
}*/

node *del(node *head,int n)//删除节点
{
    int n_1=1;
    node *p1=head,*p2=NULL;
    while(n_1!=n)//对比节点
	{
		p2=p1;//p2保存p1的位置
		p1=p1->next;//p1后移
		n_1++;//节点计数
	}
	if(n_1==n)
	{
		if(p1==head)//表头
		{
			head=p1->next;//head指向第二个节点,孤立表头
			free(p1);//释放孤立出来的节点(即从内存中删除)
		}
		else
		{
            p2->next=p1->next;//孤立出要删除的节点
            free(p1);//释放孤立出的节点(即要删除的节点)
		}
	}
	return head;
}

/*node *del(node *head,int data)
{
    node *p1=head,*p2;
    while(p1->data!=data)//对比数据域
	{
		p2=p1;//p2保存p1位置
		p1=p1->next;//p1后移
	}
	if(p1->data==data)
	{
		if(p1==head)//表头
		{
			head=p1->next;//head指向第二个节点,孤立表头
			free(p1);//释放孤立出来的节点(即从内存中删除)
		}
		else
		{
            p2->next=p1->next;//孤立出要删除的节点
            free(p1);//释放孤立出的节点(即要删除的节点)
		}
	}
	return head;
}*/

void del_a(node *head)//删除链表
{
    node *tmp,*p=head;
    while(p!=NULL)
    {
        tmp=p;//tmp保存d位置
        p=p->next;//p指向下一个节点
        free(tmp);//释放节点
    }
    head=NULL;
}

node *reverse(node *head)//逆序链表
{
    node *p1,*p2,*p3;
    if(head==NULL||head->next==NULL)
    return head;
    p2=head;//指向第一个节点
    p1=head->next;//指向第二个节点
    head->next=NULL;//第一个节点后继置空
    while(p1!=NULL)
    {
        p3=p2;//p3指向p2位置
        p2=p1;//p2指向p1位置
        p1=p1->next;//p1指向下一个节点
        p2->next=p3;//逆序节点
    }
    head=p2;//头指针指向逆序后的第一个节点
    return head;
}

/*node *reverse(node *head)
{
	node *p1,*p2,*p3;
	if(head == NULL || head->next == NULL)
    return head;

	p1=head;//指向第一个节点
	p2=head->next;//指向第二个节点
	head->next=NULL;
	while(p2!=NULL)
	{
		p3=p2->next;//将下一个节点保存下来
		p2->next=p1;//将当前节点的下一节点置为前节点
		p1=p2;//将当前节点保存为前一节点
		p2=p3;//将当前节点置为下一节点
	}
	head=p1;
	return head;
}*/

int main()
{
    int n,n1,n2;
    node *p,*p2;
    FILE *fp;
    fp=fopen("file.txt","w+");
    while(1)
    {
        printf("1 创建一个链表\n2 插入一个节点\n3 删除一个节点\n4 存储到文本file.txt\n5 删除整个链表\n6 查找数据\n7 逆序链表\n8 打印链表\n");
        scanf("%d",&n);
        switch(n)
        {
		case 1:
            printf("输入五个节点信息:\n");
            p=creat(5);
            printf("\n");
            print(p);
            break;
		case 2:
            printf("在那个节点之前插入:");
            scanf("%d",&n1);
            p=insert(p,n1);
            printf("\n");
            print(p);
            break;
		case 3:
            printf("删除那个节点:");
            scanf("%d",&n1);
            p=del(p,n1);
            printf("\n");
            print(p);
            break;
        case 4:
            printf("存储到文本file.txt\n");
            p2=p;
            for(;p2!=NULL;p2=p2->next)
            fprintf(fp,"%5d",p2->data);
            fclose(fp);
            break;
		case 5:
            printf("删除整个链表\n");
            del_a(p);
            break;
        case 6:
            printf("查找的数据:");
            scanf("%d",&n2);
            search(p,n2);
            break;
        case 7:
            printf("逆序链表\n");
            p=reverse(p);
            print(p);
            break;
        case 8:
            printf("输出链表\n");
            print(p);
            break;

        }
    }

}


单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。C语言中实现单链表基本操作包括:创建链表、插入节点、删除节点、查找节点、遍历链表等。其中,插入节点和删除节点是单链表的核心操作。在插入节点时,需要先找到要插入位置的前一个节点,然后将新节点插入到该节点之后;在删除节点时,需要先找到要删除节点的前一个节点,然后将该节点从链表中删除。以下是单链表基本操作代码示例: 1. 创建链表 ``` LinkList CreateList() { LinkList L = (LinkList)malloc(sizeof(LNode)); L->next = NULL; return L; } ``` 2. 插入节点 ``` bool ListInsert(LinkList L, int i, ElemType e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL) { return false; } LNode *s = (LNode *)malloc(sizeof(LNode)); s->data = e; s->next = p->next; p->next = s; return true; } ``` 3. 删除节点 ``` bool ListDelete(LinkList L, int i, ElemType &e) { if (i < 1) { return false; } LNode *p = L; int j = 0; while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL || p->next == NULL) { return false; } LNode *q = p->next; e = q->data; p->next = q->next; free(q); return true; } ``` 4. 查找节点 ``` LNode *GetElem(LinkList L, int i) { if (i < 1) { return NULL; } LNode *p = L->next; int j = 1; while (p != NULL && j < i) { p = p->next; j++; } return p; } ``` 5. 遍历链表 ``` void TraverseList(LinkList L) { LNode *p = L->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值