【数据结构】单链表的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CSDN___CSDN/article/details/82824660

单链表是线性表链式储存的一种形式,其中的结点一般含有两个域,一个是存放数据信息的info域,另一个是指向该结点后继结点存放地址的指针next域。一个单链表必须要有一个首指针指向链表中的第一个结点。

单链表要掌握以下几种操作:

1、建立一个空的单链表。

2、输出单链表中个结点的值。

3、在单链表中查找第i个结点。

4、在单链表的第i个结点后插入一个值为x的新结点。

5、在单链表中删除一个值为x的结点。

以下是头文件

#ifndef HEAD_LINK_H_INCLUDED
#define HEAD_LINK_H_INCLUDED

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct link_node
{
	datatype info;
	struct link_node *next;
}N;


//创建一个空链表
N *init()
{
	return NULL;
}

//创建一个单链表
N *creat(int len)
{
	int a,i;
	N *p,*head,*q;
	if (len<1)
	{
		return NULL;
	}
	else
	{
		for(i=1;i<=len;i++)
		{
			scanf("%d",&a);
			p=(N*)malloc(sizeof(N));
			p->info=a;
			if(i==1)
			{
				p->next=NULL;
				head=p;
				q=p;
			}
			else
			{
				q->next=p;
				q=p;
				p->next=NULL;
			}
		}
		return head;
	}
}

//输出单链表中各节点的值
void display (N *head)
{
	N *p=head;
	if(!p)
	{
		printf("\n该链表是空的!\n");
	}
	else
	{
		printf("\n单链表各节点的值为:\n");
		while(p)
		{
			printf("%d",p->info);
			if(p->next)
			{
				printf(" -> ");
			}
			p=p->next;
		}
		printf("\n");
	}
}

//在单链表中查找第i个节点的值
N *find(N *head ,int i)
{
	int j=1;
	N *p=head;
	if(i<1)
	{
		return NULL;
	}
	while(p && i!=j)
	{
		p=p->next;j++;
	}
	return p;
}

//在单链表中找出值为i的位置
int node_position(N* head,int i)
{
	N *p;
	int j=1;
	p=head;
	while(p && p->info!=i)
	{
		p=p->next;
		j++;
	}
	if(!p)
	{
		return 0;
	}
	else
	{
		return j;
	}
} 


//计算单链表的节点数目
int counts(N *head)
{
	N *p;
	int count=0;
	p=head;
	while(p)
	{
		count++;
		p=p->next;
	}
	return count;
}

//在单链表第i个结点后插入一个值为x的新新结点
N *insert(N *head,datatype x,int i)
{
	N *p,*q;
	q=find(head,i);/*找到第i个结点*/
	if(!q && i!=0)
	{
		printf("找不到第%d个节点,不能插入%d",i,x);
	}
	else
	{
		p=(N*)malloc(sizeof(N));
		p->info=x;
		if(i==0)
		{
			p->next=head;
			head=p;
		}
		else
		{
			p->next=q->next;
			q->next=p;
		}
	}
	return head;
}

//从单链表中删除一个值为x的节点
N *dele_num(N *head,datatype x)
{
	N *pre=NULL,*p;
	if(!head)
	{
		printf("该单链表是空的!");
		return head;
	}
	p=head;
	while(p && p->info!=x)/*没有找到并且没有找完*/
	{
		pre=p;
		p=p->next;/*pre指向p的前驱结点*/
	}
	if(p)
	{
		if(!pre)/*要删除第一个结点*/
		{
		 	head=head->next;
		}
		else
		{
			pre->next=p->next;
			free(p);
		}
	}
	return head;
}

//删除第i个结点
N *dele_node(N *head,int i)
{
	N *q,*p;
	if(!head)
	{
		printf("该单链表是空的!");
		return head;
	}
	if(i==1)
	{
		head=head->next;
	}
	else
	{
		q=find(head,i-1);
		p=find(head,i);
		q->next=p->next;		
	}
	return head;	 
}
 

void menu()
{
    printf("\t|===================================|\t\n");
    printf("\t|                                   |\t\n");
    printf("\t|          单链表的相关操作         |\t\n");
    printf("\t|                                   |\t\n");
    printf("\t|===================================|\t\n");
    printf("\t|有如下选项:                        |\t\n");
    printf("\t|===================================|\t\n");
    printf("\t|【1】初始化一个链表                |\t\n");
    printf("\t|【2】输出单链表中各结点的值        |\t\n");
    printf("\t|【3】在单链表中查找第i个结点       |\t\n");
    printf("\t|【4】在单链表中找值为i的结点的位置 |\t\n");
    printf("\t|【5】在第i个结点后插入值为x的新结点|\t\n");
    printf("\t|【6】删除值为x的结点               |\t\n");
    printf("\t|【7】删除第i个结点                 |\t\n");
    printf("\t|===================================|\t\n");
    printf("\t|Ctrl+C结束该程序!!!             |\t\n");
    printf("\t|===================================|\t\n");
}

#endif // HEAD_LINK_H_INCLUDED

下面是主程序:

#include "stdio.h"
#include "stdlib.h"
#include "head_link.h"

int main ()
{
	N *p,*q,*h1;
	int a,len,count,node_number,x,position;
	while(1)
	{
	    menu();
	    printf("请选择数字:");
	    scanf("%d",&a);
	    switch(a)
	    {
            case 1:
            {
                printf("\n请输入初始列表的长度:");
                scanf("%d",&len);
                h1=creat(len);
                break;
            }
            case 2:
            {
                display(h1);
                printf("\n现在一共有%d个节点\n",counts(h1));
                break;
            }
            case 3:
            {
                printf("输入某个节点:");
                scanf("%d",&node_number);
                if(!(find(h1,node_number)))
                {
                	printf("找不到该结点!\n");
				}
				else
				{
					printf("%d\n",(find(h1,node_number))->info);
				}
                break;
            }
            case 4:
            {	
				scanf("%d",&x);
				if(node_position(h1,x))
				{
					printf("%d\n",node_position(h1,x));
				}
				else
				{
					printf("该链表中找不到该值!\n");
				}
				break;
            }
            case 5:
            {
                printf("\n请输入要插入的数:");
                scanf("%d",&x);
                printf("请输入要插入的位置:");
                scanf("%d",&position);
                h1=insert(h1,x,position);
                display(h1);
                break;
            }
            case 6:
            {
                printf("请输入要删除的值:");
                scanf("%d",&x);
                h1=dele_num(h1,x);
                display(h1);
                break;
            }
            case 7:
            {
            	printf("当前有%d个结点,请输入要删除的结点:",counts(h1));
				scanf("%d",&node_number);
				h1=dele_node(h1,node_number);
				display(h1);
				break;
            }
	    }
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CSDN___CSDN/article/details/82824660
今日推荐