单链表的创建,删除,插入,以及合并

本人纯新手,C语言刚学了三个月,同时学了数据结构,简直受罪,单链表折磨了我好久,现在终于能理解并且能自己画图打出来了。

对于单链表不理解,无非就是对指针理解不清晰、也就是逻辑结构,对于物理结构,画图很容易理解。

头结点的作用:个人理解就是为了删除或者插入的元素位置为开头时,会比较方便。

如果没有头结点,只有头指针。那么删除或者插入的元素为开头时,需要设置一个temp指针,指向头指针,因为头指针删除后,整个链表就连不起来了。所以需要一个temp指针。


代码如下:

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


struct node{ //这是一个结点的数据结构,一个数据域放字符,一个指针域,放地址
char ch;
struct node *next;
};


struct node * creat(void){ //创建一个头指针,这个指针会把所有接下来输入的结点都连起来 现在还没有头结点
struct node *head,*p,*q; 
char x;
int i = 1;
head = 0;
printf("(#表示退出)\n请输入第%d个字符:",i);
x = getchar();getchar();//getchar()表示吸收回车
if(x == '#')
return 0;
while(x != '#'){
p = (struct node*) malloc (sizeof(struct node)); 

if(head == 0){//如果是第一个结点
head = p; //让head指向分配的第一结点
p -> ch = x;
}
else{ //如果是第二个结点
p -> ch  = x; //把字符放进数据域中
q -> next = p;//把前一个结点与当前分配的结点 连起来
}
q = p; //让q也指向当前刚分配的结点
p -> next = 0;//每次循环都会执行

printf("请输入第%d个字符:",i+1);//继续提示输入
x = getchar();getchar();
i++;
}
return(head); //返回头指针  
}


int length(struct node *a){
struct node *p; int count = 0;
p = a;

while(p){
count++;
p = p -> next;
}
return count-1; // 长度减一 是去掉头结点
}


void insert(struct node *a){
int i,k = 1;
char x;
struct node *p,*q;
p = a;
printf("\n请输入要插入的位置:");
scanf("%d",&i);getchar();
if(i < 1 || i > length(a)){
printf("插入的位置有误,程序退出");
exit(0);
}
for(k = 1; k < i; k++)
p = p -> next;

printf("\n请输入要插入的值:");
x = getchar();getchar();

q = (struct node*) malloc (sizeof(struct node)); 
q -> ch = x;

q -> next = p -> next;
p -> next = q;
}


void delete(struct node *a){
int x;
struct node *p,*q;
p = a;
q = a;
printf("\n请输入要删除的元素::");
x = getchar(); getchar();

while(p->ch != x){

q = p;
p = p -> next;
}

q -> next = p -> next;
free(p);
}


void print(struct node *a){
struct node *p;
p = a -> next;
printf("\n输入的数据为:\n");
while(p){
if( p->next == 0 ){
printf("%-2c",p->ch);
break;
}
printf("%-2c->",p->ch);
p = p->next;
}
}


void hebing(struct node *a,struct node *b){
struct node *p;
p = a;
while(p -> next){
p = p -> next;
}
p -> next = b;
printf("合并完成!!!\n");
}




void main(){
struct node *root,*root2; 
struct node head;//在主函数里做一个头结点
char choice;
puts("*************************");
puts("*      创建新表(C)      *");
puts("*      插入结点(I)      *");
puts("*      删除结点(D)      *");
puts("*      计算表长(L)      *");
puts("*      显示链表(P)      *");
puts("*      合并链表(H)      *");
puts("*      退出程序(E)      *");
puts("*************************");
printf("请输入你的选择: ");
choice = getchar(); getchar();
for(;;){
switch(choice) {
case 'c':case'C':  root = creat();//root指向(等于)头指针
head.next = root;//头结点的next连着第一个结点(因为root现在指向第一个结点)
root = &head; //root现在指向头结点  所以带头结点的链表创建完毕
print(root);
break;
case 'i':case'I':  insert(root);print(root);break;
case 'd':case'D':delete(root);print(root);break;
case 'l':case'L':  printf("\n目前一共有%d个结点\n",length(root));break;
case 'p':case'P':  print(root);break;
case 'h':case'H':printf("\n***再创建一个链表***\n");
root2 = creat();
printf("\n***两者合并***\n");
hebing(root,root2);
print(root);
break;
case 'e':case'E':printf("再见!Good Luck!!!\n");exit(0);
default : printf("输入错误,请重新输入");break;
}
printf("\n");
puts("*************************");
puts("*      创建新表(C)      *");
puts("*      插入结点(I)      *");
puts("*      删除结点(D)      *");
puts("*      计算表长(L)      *");
puts("*      显示链表(P)      *");
puts("*      合并链表(H)      *");
puts("*      退出程序(E)      *");
puts("*************************");
printf("请输入你的选择: ");
choice = getchar(); getchar();
}
}




多想 多打 多看 多画图

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值