链表的操作_C

1、单链表
单链表的存储结构:
typedef struct Node
{
ElemType Data;//数据域,此处可以为一组数据,也可以为多组数据
struct Node *Link;//指针域,该指针为指向下一节点的指针
}Node, *Linklist;

操作实例:
#include <STDIO.H>
#include <STDLIB.H>
#include <STRING.H>
#define N 10 

typedef struct node
{
char name[20];
struct node *link;
}stud;

stud * creat(int n)
{
stud *p,*h,*s;
int i;
if((h=(stud *)malloc(sizeof(stud)))==NULL)
{
printf("不能分配内存空间!");
exit(0);
}
h->name[0]='\0';
h->link=NULL;
p=h;
for(i=0;i<N;i++)
{
if((s= (stud *) malloc(sizeof(stud)))==NULL)
{
printf("不能分配内存空间!");
exit(0);
}
p->link=s;
printf("请输入第%d个人的姓名",i+1);
scanf("%s",s->name);
s->link=NULL;
p=s;
}
return(h);
}

stud * search(stud *h,char *x)
{
stud *p;
char *y;
p=h->link;
while(p!=NULL)
{
y=p->name;
if(strcmp(y,x)==0)
return(p);
else p=p->link;
}
if(p==NULL)
printf("没有查找到该数据!");
}

stud * search2(stud *h,char *x)
{
stud *p,*s;
char *y;
p=h->link;
s=h;
while(p!=NULL)
{
y=p->name;
if(strcmp(y,x)==0)
return(s);
else
{
p=p->link;
s=s->link;
}
}
if(p==NULL)
printf("没有查找到该数据!");
}

void insert(stud *p)
{
char stuname[20];
stud *s;
if((s= (stud *) malloc(sizeof(stud)))==NULL)
{
printf("不能分配内存空间!");
exit(0);
}
printf("\n请输入你要插入的人的姓名:");
scanf("%s",stuname);
strcpy(s->name,stuname);
s->link=p->link;
p->link=s;
}

void del(stud *x,stud *y)
{
stud *s;
s=y;
x->link=y->link;
free(s);
}

void print(stud *h)
{
stud *p;
p=h->link;
printf("数据信息为:\n");
while(p!=NULL)
{
printf("%s ",&*(p->name));
p=p->link;
}
}

void quit()
{
exit(0);
}

void menu(void)
{
printf("\t\t\t单链表C语言实现实例\n");
printf("\t\t|————————————————|\n");
printf("\t\t| |\n");
printf("\t\t| [1] 建 立 新 表 |\n");
printf("\t\t| [2] 查 找 数 据 |\n");
printf("\t\t| [3] 插 入 数 据 |\n");
printf("\t\t| [4] 删 除 数 据 |\n");
printf("\t\t| [5] 打 印 数 据 |\n");
printf("\t\t| [6] 退 出 |\n");
printf("\t\t| |\n");
printf("\t\t| 如未建立新表,请先建立! |\n");
printf("\t\t| |\n");
printf("\t\t|————————————————|\n");
printf("\t\t 请输入你的选项(1-6):");
}

void main()
{
int choose;
stud *head,*searchpoint,*forepoint;
char fullname[20];
while(1)
{
menu();
scanf("%d",&choose);
switch(choose)
{
case 1:
head=creat(N);
break;
case 2:
printf("输入你所要查找的人的姓名:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
printf("你所查找的人的姓名为:%s",*&searchpoint->name);
printf("\n按回车键回到主菜单。");
getchar();
getchar();
break;
case 3: 
printf("输入你要在哪个人后面插入:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
printf("你所查找的人的姓名为:%s",*&searchpoint->name);
insert(searchpoint);
print(head);
printf("\n按回车键回到主菜单。");
getchar();getchar();
break;
case 4:
print(head);
printf("\n输入你所要删除的人的姓名:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
forepoint=search2(head,fullname);
del(forepoint,searchpoint);
break;
case 5:
print(head);
printf("\n按回车键回到主菜单。");
getchar();getchar();
break;
case 6:
quit();
break;
default:
printf("你输入了非法字符!按回车键回到主菜单。");
menu();
getchar();
}
}
}

2、双向链表
双向链表的存储结构
typedef struct DulNode
{
ElemType Data;//数据域,此处可以为一组数据,也可以为多组数据
struct DulNode *lLink;//指针域,该指针为指向前驱节点的指针,也称左指针
struct DulNode *rLink;//指针域,该指针为指向后继节点的指针,也称指针
}

操作实例:

#include <STDIO.H>
#include <STDLIB.H>
#include <STRING.H>

#define NUMBER 10

/*
 * 双向链表节点的结构体
 */
typedef struct DulNode
{
char name[20];//数据域
struct DulNode *lLink;//指针域,左指针
struct DulNode *rLink;//指针域,右指针
}DulNode, *DulList;

/*
 * 创建链表,参数为链表的长度
 */
DulNode *Create(int number)
{
DulNode *pHead,*pNext,*pCur;
//为首节点分配内存
if((pHead = (DulNode*)malloc(sizeof(DulNode))) == NULL)
{
printf("内存分配失败!\n");
return NULL;
}
pHead->name[0] = '\0';
pHead->lLink = NULL;
pHead->rLink = NULL;

pCur = pHead;

for(int i=0;i<number;i++)
{
if((pNext = (DulNode*)malloc(sizeof(DulNode))) == NULL)
{
printf("内存分配失败!\n");
return NULL;
}
pCur->rLink = pNext;
printf("请输入此节点的名称:\n");
scanf("%s",pNext->name);
pNext->lLink = pCur;
pNext->rLink = NULL;
pCur = pNext;
}
return pHead;
}

/*
 * 查询操作,pList是要查询的链表,strName是要查询的元素
 */
DulNode *Search(DulNode *pList, char *strName)
{
DulNode *p;
p = pList;
char *str;
while(p != NULL)
{
str = p->name;
if(strcmp(str,strName) == 0)
{
//printf("查找成功\n");
return p;
}
p = p->rLink;
}
printf("查找失败\n");
return NULL;
}

/*
 * 插入操作,pList为操作的链表
 *  pForNode为插入节点的位置
 *  strName为插入节点元素的名称
 */
DulNode *Insert(DulNode *pList,DulNode *pForNode,char *strName)
{
DulNode *pHead,*pNode;
pHead = pList;

if((pNode = (DulNode*)malloc(sizeof(DulNode))) == NULL)
{
printf("内存分配失败!\n");
return NULL;
}
strcpy(pNode->name,strName);
pNode->rLink = pForNode->rLink;
pNode->lLink = pForNode;
pForNode->rLink = pNode;
return pHead;
}

/*
 * 删除操作,pList为操作的链表,pDelNode为要删除的元素
 */
DulNode *Delete(DulNode *pList,DulNode *pDelNode)
{
DulNode *pHead, *pNode;
pHead = pList;
pNode = pDelNode->lLink;
pNode->rLink = pDelNode->rLink;
free(pDelNode);
return pHead;
}

/*
 * 主菜单
 */
void menu()
{
printf("\t\t\t双向链表C语言实现实例\n");
printf("\t\t|————————————————|\n");
printf("\t\t| |\n");
printf("\t\t| [1] 建 立 新 表 |\n");
printf("\t\t| [2] 查 找 数 据 |\n");
printf("\t\t| [3] 插 入 数 据 |\n");
printf("\t\t| [4] 删 除 数 据 |\n");
printf("\t\t| [5] 打 印 数 据 |\n");
printf("\t\t| [6] 退 出 |\n");
printf("\t\t| |\n");
printf("\t\t| 如未建立新表,请先建立! |\n");
printf("\t\t| |\n");
printf("\t\t|————————————————|\n");
printf("\t\t 请输入你的选项(1-6):");
}

/*
 * 输出链表数据
 */
void PrintOut(DulNode *pList)
{
DulNode *pNext;
pNext = pList->rLink;
printf("此链表的数据信息为:\n");
while(pNext != NULL)
{
printf("%s\n",&*(pNext->name));
pNext = pNext->rLink;
}
}

/*
 * 主函数
 */
void main()
{
DulNode *pDulList,*pSearchNode;
int option = 0;
char strName[20];
int number = NUMBER;
while(1)
{
menu();
scanf("%d",&option);
switch(option) 
{
case 1:
pDulList = Create(number);
break;
case 2:
printf("输入要查询的数据:\n");
scanf("%s",strName);
pSearchNode = Search(pDulList,strName);
break;
case 3:
printf("输入要插入位置的数据:\n");
scanf("%s",strName);
pSearchNode = Search(pDulList,strName);
printf("输入要插入的数据:\n");
scanf("%s",strName);
pDulList = Insert(pDulList,pSearchNode,strName);
break;
case 4:
printf("输入要删除的数据:\n");
scanf("%s",strName);
pSearchNode = Search(pDulList,strName);
pDulList = Delete(pDulList,pSearchNode);
break;
case 5:
PrintOut(pDulList);
break;
case 6:
exit(0);
break;
default:
break;
}
}
}

3、循环链表
循环链表分为单链表的循环链表和双向链表的循环链表。
(1)单链表的循环链表就是将尾节点的指针指向头结点,形成循环,当判断链表尾的时候不与NULL做比较,二是判断尾节点的指针是否指向首节点。
(2)双向链表的循环链表就是将尾节点的右指针指向头结点,将头结点的左指针指向尾节点,形成循环,判断链表尾的时候如果单链表的循环链表。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值