实现各种链表操作,写了一个链表操作界面

//********************************************************************************************
//***********************************作者:刘建***********************************************
//***********************************日期:2016-07-26*****************************************
//***********************************链表的各种操作*******************************************
//********************************************************************************************


#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>//system("cls")清屏需要的库


typedef int elemtype;
typedef struct node{
elemtype data;
struct node * next;
}LinkList;


//------创建带有头结点的单链表,长度为n------
LinkList* CreateLinkList(int n,int flag)//flag=0则头插法,flag=1则尾插法。
{
int i;
LinkList *L,*r;//建立头结点
LinkList *p; //创建一个工具指针,用于插入数据。
L=(LinkList *)malloc(sizeof(LinkList));//为头结点分配空间,数据存的长度信息,指针指向空。
L->data=n; //长度信息放到头结点
L->next=NULL; //C语言中空必须大写“NULL”
r=L;
if (0==flag){
for (i=0;i<n;i++){
p=(LinkList *)malloc(sizeof(LinkList));
printf("-----------请输入第%d个元素的值-----------\n",(i+1));
scanf("%d",&p->data);//输入链表元素
p->next=L->next;//与插入结点的原理相似
L->next=p; //头插法:先接棒再牵手
}
printf("-----------创建成功!----------------------\n");
}
else if(1==flag){
for (i=0;i<n;i++){
p=(LinkList *)malloc(sizeof(LinkList));
printf("-----------请输入第%d个结点的值-----------\n",(i+1));
scanf("%d",&p->data);//输入链表元素
r->next=p;
r=p;//尾插法:先牵手再接棒,r始终指向最后一个结点,作为工具,而头插法不需要工具。
}
r->next=NULL;
printf("-----------创建成功!----------------------\n");
}
else
printf("-----------请输入正确的方法代码(0/1)!----------------------\n");
return L;
}


//------遍历打印链表元素,及长度------
void PrintLinkList(LinkList *L)
{
LinkList *p,*head_node;
p=L;
unsigned int n=0;
if (NULL==L)
printf("-----------请先创建链表!-------\n");
else if(NULL==L->next)
printf("-----------是空链表!-----------\n");
else
{
while(p)
{
if(0==n)
{
head_node=p;
p=p->next;
n++;
}
else
{
printf("-----------第%d个结点是:%d----------------------------------------------\n",n,p->data);
p=p->next;
n++;
}
}
head_node->data=n;
printf("-----------共%d个结点,头结点储存链表长度信息:%d-----------------\n",n,head_node->data);
}
}


//链表是否为空
bool isEmpty(LinkList *L)
{
if (NULL==L->next)//带头结点的判断,不带头结点则 (!L)
return true;
else
return false;
}


//插入结点
void InsertNode(LinkList *L,int pos,elemtype e)
{
int i=1;//因为从第一个开始算,第0个是头结点。
LinkList *p,*s;//建两个指针工具,一个用来遍历,一个用来生成新节点。
p=L;//这个工具来p=p->next遍历链表,如果使用L的话,链表改变,全乱套。
while(p && i<pos)
{
i++;
p=p->next;
}//找到插入的位置pos

if(!p || i>pos)//错误的情况:无后继或者找不到位置。
printf("位置错误或空表,请重新输入:");
else
{
//别忘记!!!生成一个新节点,并插入的时候必须要动态分配内存,不管是生成表还是插入值。
s=(LinkList *)malloc(sizeof(LinkList));
s->data=e;
s->next=p->next;//工具p查到的那个点进行插入,*L一直指向头的,不能用L。
p->next=s;
}
}


//删除结点
elemtype DeleteNode(LinkList *L,int pos)
{
int i=1;
elemtype data;
LinkList *p,*q;
p=L;
while(p && i<pos)
{
i++;
p=p->next;
}//找到插入的位置pos
if(!p || i>pos)//错误的情况!:无后继或者找不到位置。
{
printf("位置错误或空表,请重新输入:");
return -1;//错误标识
}
else
{
q=p->next;//你要删除它,就先用指针工具指着它!
p->next=q->next;
data=q->data;
free(q);//释放删除的结点
printf("删除的节点值为:%d",data);
return data;
}
}


//删除链表
bool DeleteList(LinkList *L)
{
LinkList *p,*q;

if(!L)//是否创建了链表,有头结点
{
printf("请先创建链表!\n");
return false;

}else{
p=L->next;//因为是free(p),不能把头结点也删掉,太过分。
while(p)
{
q=p->next;
free(p);
p=q;
}
L->next=NULL;//p指针free完,但头结点还在,需要指空
return true;
}
}


void LinkList_Operation(int cursor)//链表操作
{
static LinkList *List=NULL;//函数都能修改它


switch(cursor){
case 1:
{
printf("创建链表\n");
unsigned int size,flag;
printf("请输入链表的长度:\n");
scanf("%d",&size);
printf("请选择头插法/尾插法(0/1):\n");
scanf("%d",&flag);
List = CreateLinkList(size,flag);
printf("\n\n");
break;
}
case 2:
{
printf("-------------------打印链表:-------------------\n");
PrintLinkList(List);
printf("\n\n");
break;
}
case 3:
{
if (isEmpty(List))
printf("链表为空\n");
else
printf("链表不为空\n");
printf("\n\n");
break;
}
case 4:
{
unsigned int pos;
elemtype data;
printf("-------插入结点-------\n");
printf("插入位置:pos= \n");
scanf("%d",&pos);//使用scanf别忘了&
printf("插入数据:data= \n");
scanf("%d",&data);
InsertNode(List,pos,data);
printf("\n\n");
break;
}


case 5:
{
printf("删除结点\n");
unsigned int pos;
printf("请输入删除节点的位置\n");
scanf("%d",&pos);
printf("删除的结点值为:%d",DeleteNode(List,pos));
printf("\n\n");
break;
}
case 6:
{
printf("删除链表\n");
if(DeleteList(List))
printf("删除成功!\n");
else
printf("删除失败!\n");
printf("\n\n");
break;
}
case 7:
{
printf("退出操作\n");
printf("\n\n");
break;
}
default :
printf("输入错误,请重新输入:\n");
break;
}
}




int main(){
unsigned int cursor; //选择操作

//char c;
while(cursor!=7)
{
/*用于监听回车键
while((c = getchar()) != EOF)
{
if(c == '\n')
{
system("cls");//回车则清屏
break;
}
}*/
printf("--------欢迎来到单链表操作(带头结点),请选择---------\n");
printf("--------------------1.创建链表-----------------------\n");
printf("--------------------2.打印链表-----------------------\n");
printf("--------------------3.链表是否为空-------------------\n");
printf("--------------------4.插入结点-----------------------\n");
printf("--------------------5.删除结点-----------------------\n");
printf("--------------------6.删除链表-----------------------\n");
printf("--------------------7.退出操作-----------------------\n");
scanf("%d",&cursor);
LinkList_Operation(cursor);//进入操作
}

printf("------------------退出,欢迎下次使用!---------------\n\n\n\n");
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值