#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"ctype.h"
typedef struct node //定义结点
{
char data[10]; //结点的数据域为字符串
struct node *next; //结点的指针域
}ListNode;
typedef ListNode * LinkList; //自定义LinkList单链表类型
LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表
LinkList CreatList(void); //函数,用头插入法建立带头结点的单链表
ListNode *LocateNode(LinkList,char*); //函数,按值查找结点
void DeleteList(LinkList,char*); //函数,删除指定值的结点
void PrintList(LinkList); //函数,打印链表中的所有值
void DeleteAll(LinkList); //函数,删除所有结点,释放内存
ListNode * AddNode(LinkList); //修改程序:增加结点。用尾插法,返回头指针
int main(){
char ch[10],num[5];
LinkList head;
int t1;
printf("输入建立链表的方式:1.尾插入 2.头插入\n");
scanf("%d",&t1);
if(t1==1){
head=CreatListR1(); //用尾插入法建立单链表,返回头指针
PrintList(head); //遍历链表输出其值
printf("\n");
printf(" 删除结点 (y:删除,n:下一步):"); //输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
printf("输入要删除的字符串:");
scanf("%s",ch); //输入要删除的字符串
DeleteList(head,ch);
PrintList(head);
}
printf("\n");
printf(" 插入结点 (y:插入,n:下一步)"); //输入"y"或"n"去选择是否增加结点
scanf("%s",num);
if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
head=AddNode(head);
}
PrintList(head);
printf("\n");
printf("释放所有结点,程序结束");
DeleteAll(head); //删除所有结点,释放内存
} else{
head=CreatList(); //用头插入法建立单链表,返回头指针
PrintList(head); //遍历链表输出其值
printf("\n");
printf(" 删除结点 (y:删除,n:下一步):"); //输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
printf("输入要删除的字符串:");
scanf("%s",ch); //输入要删除的字符串
DeleteList(head,ch);
PrintList(head);
}
printf("\n");
printf(" 插入结点 (y:插入,n:下一步)"); //输入"y"或"n"去选择是否增加结点
scanf("%s",num);
if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
head=AddNode(head);
}
PrintList(head);
printf("\n");
printf("释放所有结点,程序结束");
DeleteAll(head); //删除所有结点,释放内存
}
return 1;
}
//头插入法建立带头结点的单链表
LinkList CreatList(void)
{
char ch[10];
LinkList head, p;
head=(LinkList)malloc(sizeof(ListNode));
head->next=NULL;
printf("输入字符串个数\n");
int n;
scanf("%d",&n);
printf("输入字符串\n");
for(int i=0;i<n;i++){
scanf("%s",ch);
if(LocateNode(head,ch)==NULL) //如果没有字符串是重复的
{
strcpy(head->data,ch);
//前插法插入新的结点
p=(LinkList)malloc(sizeof(ListNode));
p->next=head;
head=p;
}
}
return head;
}
//尾插入法建立带头结点的单链表
LinkList CreatListR1(void)
{
char ch[100];
LinkList head, p;//head为头结点,p为首元结点
head=(LinkList)malloc(sizeof(ListNode));
head->next=NULL;
LinkList temp=head;
printf("输入字符串个数:");
int n;
scanf("%d",&n);
printf("输入字符串 \n");
for(int i=0;i<n;i++){
scanf("%s",ch);
if(LocateNode(head,ch)==NULL) //如果没有字符串是重复的
{
//尾插法插入新的结点
//遍历到尾结点
while (temp->next!=NULL) temp=temp->next;
p=(LinkList)malloc(sizeof(ListNode));
strcpy(p->data,ch);
p->next=NULL;
temp->next=p;
}
}
return head;
}
//按值查找结点,找到则返回该结点的位置,否则返回NULL
ListNode *LocateNode(LinkList head, char *key)
{
//创建临时结点作为储存
LinkList temp=head->next;
while (temp!=NULL)
{
//如果有与key匹配的值,就退出循环
if (strcmp(temp->data,key)==0) break;
//没有找到就继续找
else temp=temp->next;
}
//找到就返回这个结点的地址,没有找到就返回NULL(循环的方式决定的)
return temp;
}
// 修改程序:增加结点
ListNode * AddNode(LinkList head)
{
char ch[100];
LinkList p,temp=head;
printf("输入要插入的字符串(在尾部插入)\n");
scanf("%s",ch);
if(LocateNode(head,ch)==NULL) //如果没有字符串是重复的,就执行下面的语句
{
//尾插法插入新的结点
//遍历到尾结点
while (temp->next!=NULL) temp=temp->next;
p=(LinkList)malloc(sizeof(ListNode));
strcpy(p->data,ch);
p->next=NULL;
temp->next=p;
}
return head;
}
// 删除带头结点的单链表中的指定结点
void DeleteList(LinkList head,char *key)
{
//创建临时结点作为储存
LinkList temp=head->next;
LinkList above=temp;
while (temp!=NULL)
{
//如果找到相同值,就将前驱结点的next指向后继结点temp->next,并将temp结点删除
if (strcmp(temp->data,key)==0){
above->next=temp->next;
free(temp);
temp=NULL;
break;
}
//没有找到就继续找,
else{
above=temp;
temp=temp->next;
}
}
}
// 打印链表
void PrintList(LinkList head)
{
//创建临时结点作为储存
LinkList temp=head->next;
printf("链表中data的值:\n");
while (temp!=NULL)
{
//循环打印数据
printf("%s ",temp->data);
temp=temp->next;
}
}
// 删除所有结点,释放空间
void DeleteAll (LinkList head)
{
//创建临时结点作为储存
LinkList temp=head,free_node;
while (temp!=NULL)
{
//用free_node储存即将释放的结点,并将temp指向下一个之后,释放
free_node=temp;
temp=temp->next;
free(free_node);
free_node=NULL;
}
}
C语言:顺序链表的插入与删除(整个程序)
于 2022-04-25 20:31:56 首次发布