S1E47:单链表3(中间插入) 课后作业

动动手:
0. 请编写一个程序,将用户录入的整数从小到大存储为单链表 a,然后将单链表a原地反转并输出(从大到小存储)。
程序实现如下:

答:参考了答案,略有区别

#include <stdio.h>
#include <stdlib.h>
    
struct Node
{
        int value;
        struct Node *next;
};
    
void insertNode(struct Node **head, int value)
{
      struct Node *cur;
      struct Node *pre; //当前值的上一级
	  struct Node *new; 
      
      
      cur = *head;
      pre = NULL;
      
      while(cur != NULL && cur->value < value)
      {
      		pre = cur; //pre为当前值的上一级 
      		cur = cur->next;
	  }//已经轮询到该有的地方了
	  	  	  
	  new = (struct Node *)malloc(sizeof(struct Node));
	  new->value = value;
	  new->next = cur; //定位new的下一个节点 
	  
	  if(pre == NULL)
	  {
			*head = new;  //第一次进来把 new赋为new
	  }
	  else
	  {
	  		pre->next = new; //定位new的上一个节点 
	  }
	   	   
}
    
void printNode(struct Node *head)
{
	struct Node *cur;
	cur = head;
	while(cur != NULL)
	{
		printf("%2d",cur->value);
		cur = cur->next;
	
	}	
	printf("\n");
}
    
    
    
//链表的翻转 这里的逻辑没明白   
struct Node *reversed(struct Node *head)
{
	struct Node *pre;
	struct Node *cur;
	
	pre = NULL;
	cur = head;
	
	struct Node *temp = NULL;
	while(cur != NULL)
	{
		temp = cur->next;  //把cur后面的都承接,备份了 
		
		//这一步为翻转操作,链表的方向发生了改变 
		cur->next = pre;   
		
		//把cur给到pre ,进行下一个节点的翻转操作 
		pre = cur;        
		
		//保留的临时节点给cur 
		cur = temp; 
	}
	return pre; 
}
    
int main(void)
{
	int input;
	struct Node *head = NULL;
	printf("开始录入数据到单链表a..."); 
	while(1)
	{
		printf("请输入一个整数(输入-1表示结束):") ;
		scanf("%d",&input);
		if(input == -1)
			break;  //如果放在while判断下会输入进链表 
		insertNode(&head,input);
		printNode(head);
		
	}
		
	printf("下面将单链表a原地反转...\r\n");
	head = reversed(head);
	printNode(head);
	

}

答案:

#include <stdio.h>
#include <stdlib.h>
    
struct Node
{
        int value;
        struct Node *next;
};
    
void insertNode(struct Node **head, int value)
{
        struct Node *pre;
        struct Node *cur;
        struct Node *new;
    
        cur = *head;
        pre = NULL;
    
        while (cur != NULL && cur->value < value)
        {
                pre = cur;
                cur = cur->next;
        }
    
        new = (struct Node *)malloc(sizeof(struct Node));
        if (new == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
        new->value = value;
        new->next = cur;
    
        if (pre == NULL)
        {
                *head = new;
        }
        else
        {
                pre->next = new;
        }
}
    
void printNode(struct Node *head)
{
        struct Node *cur;
    
        cur = head;
        while (cur != NULL)
        {
                printf("%d ", cur->value);
                cur = cur->next;
        }
        putchar('\n');
}
    
struct Node *reversed(struct Node *head)
{
        struct Node *pre;
        struct Node *cur;
    
        pre = NULL;
        cur = head;
        while(cur)
        {
                struct Node *next = cur->next;
                cur->next = pre;
                pre = cur;
                cur = next;
        }
    
        return pre;
}
    
int main(void)
{
        struct Node *head = NULL;
        int input;
    
        printf("\n开始录入数据到单链表a...\n");
        while (1)
        {
                printf("请输入一个整数(输入-1表示结束):");
                scanf("%d", &input);
                if (input == -1)
                {
                        break;
                }
                insertNode(&head, input);
                printNode(head);
        }
    
        printf("\n下面将单链表a原地反转...\n");
        head = reversed(head);
        printNode(head);
    
        return 0;
}

1. 请编写一个程序,将用户录入的整数存储为单链表,并检查该单链表是否为回文链表。
提示:可以同时使用“头插法”和“尾插法”存储两个单链表,然后比较两者是否相同即可判断是否为回文链表。
程序实现如下:

答案:

#include <stdio.h>
#include <stdlib.h>
    
struct Node
{
        int value;
        struct Node *next;
};
    
void insertHead(struct Node **head, int value)
{
        struct Node *cur;
        struct Node *temp;
    
        cur = (struct Node *)malloc(sizeof(struct Node));
        if (cur == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        cur->value = value;
    
        if (*head != NULL)
        {
                temp = *head;
                *head = cur;
                cur->next = temp;
        }
        else
        {
                *head = cur;
                cur->next = NULL;
        }
}
    
void insertTail(struct Node **head, int value)
{
        struct Node *cur;
        struct Node *temp;
    
        cur = (struct Node *)malloc(sizeof(struct Node));
        if (cur == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        cur->value = value;
    
        if (*head != NULL)
        {
                temp = *head;
                while (temp->next != NULL)
                {
                        temp = temp->next;
                }
    
                temp->next = cur;
                cur->next = NULL;
        }
        else
        {
                *head = cur;
                cur->next = NULL;
        }
}
    
void printNode(struct Node *head)
{
        struct Node *cur;
    
        cur = head;
        while (cur != NULL)
        {
                printf("%d ", cur->value);
                cur = cur->next;
        }
        putchar('\n');
}
    
int recurCheck(struct Node *head, struct Node *tail)
{
        while (head)
        {
                if (head->value != tail->value)
                {
                        return 0;
                }
                head = head->next;
                tail = tail->next;
        }
    
        return 1;
}
    
int main(void)
{
        struct Node *head = NULL;
        struct Node *tail = NULL;
        int input;
    
        while (1)
        {
                printf("请输入一个整数(输入-1表示结束):");
                scanf("%d", &input);
                if (input == -1)
                {
                        break;
                }
                insertHead(&head, input);
                insertTail(&tail, input);
        }
    
        printf("录入的单链表是:");
        printNode(tail);
    
        if (recurCheck(head, tail))
        {
                printf("录入的单链表是回文链表!\n");
        }
        else
        {
                printf("录入的单链表不是回文链表!\n");
        }
    
        return 0;
}

2. 请编写一个程序,将用户录入的整数从小到大存储为单链表a,然后删除单链表a中重复的数字并打印结果。
程序实现如下:

答:

#include <stdio.h>
#include <stdlib.h>

struct Node
{
	int value;
	struct Node *next;	
};


void insertNode(struct Node **head, int value)
{
      struct Node *cur;
      struct Node *pre; //当前值的上一级
	  struct Node *new; 
      
      cur = *head;
      pre = NULL;
      
     while(cur != NULL && cur->value < value)
      {
      		pre = cur; //pre为当前值的上一级 
      		cur = cur->next;
	  }//已经轮询到该有的地方了
	  	  	  
	  new = (struct Node *)malloc(sizeof(struct Node)); 
	  if (new == NULL)
      {
            printf("内存分配失败!\n");
            exit(1);
	  }
	  
	  new->value = value;
	  new->next = cur; //定位new的下一个节点 
	  
	  if(pre == NULL)
	  {
			*head = new;  //第一次进来把 new赋为new
	  }
	  else
	  {
	  		pre->next = new; //定位new的上一个节点 
	  }
	   	   
}

void printNode(struct Node *head)
{
	struct Node *cur;
	cur = head;
	while(cur != NULL)
	{
		printf("%2d",cur->value);
		cur = cur->next;
	
	}	
	printf("\n");
}

 
struct Node *deleteDup(struct Node *head)
{
	struct Node *cur = head;
	
	struct Node *temp = NULL;
	
	while(cur->next != NULL)  //这里的判断是下一个为空才退出 
	{
		temp = cur->next;
		if(cur->value == temp->value)
		{
			cur->next = temp->next;
		}
		else
		{
			cur = temp;
		}
	
	}
	return head; 
}


int main(void)
{
	int input;
	struct Node *head = NULL;
	
	printf("开始录入数据到单链表a..."); 
	while(1)
	{
		printf("请输入一个整数(输入-1表示结束):") ;
		scanf("%d",&input);
		if(input == -1)
		{
			break;  //如果放在while判断下会输入进链表
		}
			 
		insertNode(&head,input);
	}
	printf("输入的单链表是:"); 
	printNode(head);	
	printf("去重之后的单链表是:");
	head = deleteDup(head);
	printNode(head);
	

}


答案:

#include <stdio.h>
#include <stdlib.h>
    
struct Node
{
        int value;
        struct Node *next;
};
    
void insertNode(struct Node **head, int value)
{
        struct Node *pre;
        struct Node *cur;
        struct Node *new;
    
        cur = *head;
        pre = NULL;
    
        while (cur != NULL && cur->value < value)
        {
                pre = cur;
                cur = cur->next;
        }
    
        new = (struct Node *)malloc(sizeof(struct Node));
        if (new == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        new->value = value;
        new->next = cur;
    
        if (pre == NULL)
        {
                *head = new;
        }
        else
        {
                pre->next = new;
        }
}
    
void printNode(struct Node *head)
{
        struct Node *cur;
    
        cur = head;
        while (cur != NULL)
        {
                printf("%d ", cur->value);
                cur = cur->next;
        }
        putchar('\n');
}
    
struct Node *deleteDup(struct Node *head)
{
        if(head == NULL)
        {
                return head;
        }
    
        struct Node *cur = head;
        while (cur->next)
        {
                if (cur->value == cur->next->value)
                {
                        cur->next = cur->next->next;
                }
                else
                {
                        cur = cur->next;
                }
        }
    
        return head;
}
    
int main(void)
{
        struct Node *head = NULL;
        struct Node *new = NULL;
        int input;
    
        while (1)
        {
                printf("请输入一个整数(输入-1表示结束):");
                scanf("%d", &input);
                if (input == -1)
                {
                        break;
                }
                insertNode(&head, input);
        }
    
        printf("输入的单链表是:");
        printNode(head);
        printf("去重之后的单链表是:");
        new = deleteDup(head);
        printNode(new);
    
        return 0;
}

3. 请结合单链表和堆处理函数实现一个通讯录管理程序,下面给出了程序的基本实现逻辑:

程序实现如下:

答:我采用的头插法,删除联系人函数逻辑参考了答案

#include <stdio.h>
#include <stdlib.h>

struct Node
{
	char name[32];
	char number[32];
	struct Node *next;
};


//用的头插法 
void addPerson(struct Node **head)
{
	struct Node *cur = NULL;
	struct Node *temp = NULL;
	
	cur = (struct Node *)malloc(sizeof(struct Node));
	if(cur == NULL)
	{
		printf("内存分配失败!\r\n");
		exit(1); 	
	}
	
	printf("请输入联系人:");
	scanf("%s",cur->name);
	printf("请输入电话:");
	scanf("%s",cur->number);	
	
	if(*head != NULL)
	{
		temp = *head;
		*head = cur;
		cur->next= temp; 
	}
	else
	{
		*head = cur;
		cur->next=NULL;		
	}
}


struct Node *findPerson(struct Node *head)
{
	char nameinput[32] = {0}; 
	struct Node *temp = head;
	printf("请输入联系人:");
	scanf("%s",nameinput);

	while(temp != NULL)
	{
			if(!strcmp(temp->name,nameinput))
			{
				printf("电话:%s\n",temp->number); 
				break;
			}	
		temp = temp->next; 
	}
	return temp;
} 


void changePerson(struct Node *head)
{
	struct Node *temp = NULL; 
	char nameinput[32]={0};
	
	temp = findPerson(head);	
	if(temp == NULL)
	{
		printf("找不到该联系人\r\n");
	}
	else
	{
		printf("请输入新的联系电话:");
		scanf("%s",temp->number);
	}
}


void delPerson(struct Node **head)
{
	struct Node *pre = NULL;
	struct Node *temp = NULL;
	struct Node *cur = NULL; 
	
	char inputname[32]={0};
	
	cur = findPerson(*head);
		
	if(cur == NULL)
	{
		printf("没有该联系人\r\n");
	}
		
	else
	{
		temp = *head;
		while(temp != NULL && temp != cur)
		{
			pre = temp;
			temp = temp->next;
		}
		
		if(pre == NULL)
		{
			*head = cur;
		}
		else{
			
			pre->next= cur->next;
		}
	} 
}


//显示所有联系人 
void displayPerson(struct Node *head)
{
	struct Node *temp = head;
	while(temp != NULL)
	{
		printf("联系人:%s",temp->name);
		printf("电话%s",temp->number);
		temp = temp->next;
	}	
}


//释放内存 
void releaseContacts(struct Node **head)
{
	struct Node *temp = NULL;
	while(*head != NULL)
	{
		temp = *head;
		*head = (*head)->next;
		free(temp);
		
	}
}



int main()
{
	int input = 0;
	printf("|  欢迎使用通讯录管理程序  |\r\n");
	printf("|---  1:插入新的联系人  ---|\r\n");	
	printf("|---  2:查找已有联系人  ---|\r\n");
	printf("|---  3:更改已有联系人  ---|\r\n");
	printf("|---  4:删除已有联系人  ---|\r\n");
	printf("|---  5:显示已有联系人  ---|\r\n");
	printf("|---  6:退出通讯录程序  ---|\r\n");
	
	
	struct Node *person = NULL;
	while(1)
	{
		printf("请输入指令代码:");
		scanf("%d",&input);
		switch(input){
			case 1:
				addPerson(&person);
				break;
			case 2:
				findPerson(person);
				break;	
			case 3:
				changePerson(person);
				break;
			case 4:
				delPerson(&person);
				break;
			case 5:
				displayPerson(person);
				break;
			case 6:
				releaseContacts(&person);
				break;		
			default:
				break;
		}
		printf("\n");	
	}
		
} 

答案:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
    
struct Person
{
        char name[40];
        char phone[20];
        struct Person *next;
};
    
void getInput(struct Person *person);
void printPerson(struct Person *person);
void addPerson(struct Person **contacts);
void changePerson(struct Person *contacts);
void delPerson(struct Person **contacts);
struct Person *findPerson(struct Person *contacts);
void displayContacts(struct Person *contacts);
void releaseContacts(struct Person **contacts);
    
void getInput(struct Person *person)
{
        printf("请输入姓名:");
        scanf("%s", person->name);
        printf("请输入电话:");
        scanf("%s", person->phone);
}
    
void addPerson(struct Person **contacts)
{
        struct Person *person;
        struct Person *temp;
    
        person = (struct Person *)malloc(sizeof(struct Person));
        if (person == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        getInput(person);
    
        // 将person用头插法添加到通讯录中
        if (*contacts != NULL)
        {
                temp = *contacts;
                *contacts = person;
                person->next = temp;
        }
        else
        {
                *contacts = person;
                person->next = NULL;
        }
}
    
void printPerson(struct Person *person)
{
        printf("联系人:%s\n", person->name);
        printf("电话:%s\n", person->phone);
}
    
struct Person *findPerson(struct Person *contacts)
{
        struct Person *current;
        char input[40];
    
        printf("请输入联系人:");
        scanf("%s", input);
    
        current = contacts;
        while (current != NULL && strcmp(current->name, input))
        {
                current = current->next;
        }
    
        return current;
}
    
void changePerson(struct Person *contacts)
{
        struct Person *person;
    
        person = findPerson(contacts);
        if (person == NULL)
        {
                printf("找不到该联系人!\n");
        }
        else
        {
                printf("请输入新的联系电话:");
                scanf("%s", person->phone);
        }
}
    
void delPerson(struct Person **contacts)
{
        struct Person *person;
        struct Person *current;
        struct Person *previous;
    
        // 先找到待删除的节点指针
        person = findPerson(*contacts);
        if (person == NULL)
        {
                printf("找不到该联系人!\n");
        }
        else
        {
                current = *contacts;
                previous = NULL;
    
                // current定位到待删除的节点
                while (current != NULL && current != person)
                {
                        previous = current;
                        current = current->next;
                }
    
                if (previous == NULL)
                {
                        // 待删除的节点是第一个节点
                        *contacts = current->next;
                }
                else
                {
                        // 待删除的节点不是第一个节点
                        previous->next = current->next;
                }
    
                free(person);
        }
}
    
void displayContacts(struct Person *contacts)
{
        struct Person *current;
    
        current = contacts;
        while (current != NULL)
        {
                printPerson(current);
                current = current->next;
        }
}
    
void releaseContacts(struct Person **contacts)
{
        struct Person *temp;
    
        while (*contacts != NULL)
        {
                temp = *contacts;
                *contacts = (*contacts)->next;
                free(temp);
        }
}
    
int main(void)
{
        int code;
        struct Person *contacts = NULL;
        struct Person *person;
    
        printf("| 欢迎使用通讯录管理程序 |\n");
        printf("|--- 1:插入新的联系人 ---|\n");
        printf("|--- 2:查找已有联系人 ---|\n");
        printf("|--- 3:更改已有联系人 ---|\n");
        printf("|--- 4:删除已有联系人 ---|\n");
        printf("|--- 5:显示当前通讯录 ---|\n");
        printf("|--- 6:退出通讯录程序 ---|\n");
        printf("|- Powered by FishC.com -|\n");
    
        while (1)
        {
                printf("\n请输入指令代码:");
                scanf("%d", &code);
                switch (code)
                {
                        case 1: addPerson(&contacts); break;
    
                        case 2: person = findPerson(contacts);
                                if (person == NULL)
                                {
                                        printf("找不到该联系人!\n");
                                }
                                else
                                {
                                        printPerson(person);
                                }
                                break;
    
                        case 3: changePerson(contacts); break;
    
                        case 4: delPerson(&contacts); break;
    
                        case 5: displayContacts(contacts); break;
    
                        case 6: goto END;
                }
        }

END:
        releaseContacts(&contacts);
    
        return 0;
}


&.gic4NphM>,WdA?-K@8)rB(TH
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值