C语言实现数据结构:链表

第四周作业

作业题目1:

程序运行结果截图,需测试各种情况。写出测试过程中遇到的主要问题及所采用的解决措施。

运行结果截图:

主要问题:指针的&和*用法不清楚

解决办法:多次进行调试,最终尝试得到结果

代码:

linklist.h

#pragma once
#include"function.h"

struct Node
{
	int data;
	struct Node* next;
};
  • function.h
  • #pragma once
    #include<stdio.h>
    #include<stdlib.h>
    
    struct Node* createlist();//创建链表
    void printList(struct Node* headNode);//查看链表
    void insertNodeByhead(struct Node* headNode, int data);//头插
    void deleteNodeByAppoin(struct Node* headNode, int posdata);//指定位置删除
    int locateNode(struct Node* headNode, int data);//查找
    int initList(struct Node* list);//初始化链表
    void recursive_reverse(struct Node* head);//链表的就地反转

    function.cpp

  • #include"linklist.h"
    struct Node* createlist()
    {
    	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
    	headNode->data = 0;
    	headNode->next = NULL;
    	return headNode;
    }
    
    struct Node* createNode(int data)
    {
    	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    	newNode->data = data;
    	newNode->next = NULL;
    	return newNode;
    }
    
    void printList(struct Node* headNode)
    {
    	struct Node* pMove = headNode->next;
    	if (pMove == NULL)
    	{
    		printf("链表为空!");
    	}
    	else
    	{
    		while (pMove)
    		{
    			printf("%d ", pMove->data);
    			pMove = pMove->next;
    		}
    	}
    	printf("\n");
    }
    
    void insertNodeByhead(struct Node* headNode, int data)
    {
    	struct Node* newNode = createNode(data);
    	newNode->next = headNode->next;
    	headNode->next = newNode;
    }
    
    void deleteNodeByAppoin(struct Node* headNode, int posdata)
    {
    	struct Node* posNode = headNode->next;
    	struct Node* posNodeFront = headNode;
    	if (posNode == NULL)
    	{
    		printf("无法删除链表为空!\n");
    	}
    	else
    	{
    		while (posNode->data != posdata)
    		{
    			posNodeFront = posNode;
    			posNode = posNode->next;
    			if (posNode == NULL)
    			{
    				printf("未找到指定元素!\n");
    				return;
    			}
    		}
    		posNodeFront->next = posNode->next;
    		printf("删除成功!\n");
    		free(posNode);
    	}
    }
    
    int locateNode(struct Node* headNode, int data)
    {
    	struct Node* p = headNode->next;
    	int i=1;
    	while (p->next!=NULL) {
    		if (p->data != data) {
    			i++;
    			p = p->next;
    		}
    		else {
    			return i;
    		}
    	}
    	printf("没有找到数据\n");
    	return -1;
    }
    
    int initList(struct Node* list)
    {
    	struct Node* p;
    	struct Node* q;
    	p = list->next;
    	while (p)
    	{
    		q = p->next;
    		free(p);
    		p = q;
    	}
    	list->next = NULL;
    	return 1;
    }
    
    void recursive_reverse(struct Node* head)
    {
    	if (head->next == NULL) return;
    
    	struct Node* pre = NULL;
    	struct Node* cur = head->next;
    	struct Node* next;
    
    	while (cur) {
    		next = cur->next;
    		cur->next = pre;
    		pre = cur;
    		cur = next;
    	}
    
    	head->next = pre;
    }

    linklist.cpp

  • #include"linklist.h"
    void menu()
    {
    	printf("[1]创建链表\n");
    	printf("[2]头插元素\n");
    	printf("[3]查看链表\n");
    	printf("[4]删除元素\n");
    	printf("[5]查找元素\n");
    	printf("[6]清空链表\n");
    }
    int main()
    {
    	struct Node* list = createlist();
    	menu();
    	printf("请输入操作\n");
    	while (1)
    	{
    		int choose = 0;
    		int item = 0;
    		int del = 0;
    		int loc = 0;
    		scanf_s("%d", &choose);
    		switch (choose)
    		{
    		case 1:
    		{
    			struct Node* list = createlist();
    			printf("链表创建成功!\n");
    				printf("\n请输入操作\n");
    			break;
    		}
    
    		case 2:
    		{
    			printf("请分别输入数据,且以-1结尾\n");
    			while (1)
    			{
    				scanf_s("%d", &item);
    				if (item == -1)
    				{
    					break;
    				}
    				insertNodeByhead(list, item);
    			}
    			recursive_reverse(list);
    			printf("\n请输入操作\n");
    			break;
    		}
    		case 3:
    		{
    			printf("链表元素如下:\n");
    			printList(list);
    			printf("\n请输入操作\n");
    			break;
    		}
    		case 4:
    		{
    
    			printf("请输入要删除的元素:\n");
    			scanf_s("%d", &del);
    			deleteNodeByAppoin(list, del);
    			printf("\n请输入操作\n");
    			break;
    		}
    		case 5:
    		{
    			printf("请输入要查找的元素:\n");
    			scanf_s("%d", &loc);
    			if (locateNode(list, loc))
    				printf("所查找元素的位置为:%d\n", locateNode(list, loc));
    			else
    				printf("您查找的数值不存在。\n");
    			printf("\n请输入操作\n");
    			break;
    		}
    		case 6:
    		{
    			initList(list);
    			printf("清空成功!\n");
    			printf("\n请输入操作\n");
    		}
    		}
    	}
    	system("pause");
    	return 0;
    }
    

作业题目2:

1.题目描述:

假设有一个带头结点的单链表L={a1,b1,a2,b2,…,an,bn}。设计一个算法将其拆分成两个带头结点的单链表L1和L2:L1={a1,a2,…,an},L2={bn,bn-1,…,b1},要求L1使用L的头结点。

2.问题分析:

(1)程序的功能要求;把链表拆分并反向

(2)程序的界面设计:分别为:请输入链表中的元素个数,请输入链表中的元素,链表L1中的元素为,链表L2中的元素为

(3)程序的错误处理:当输入链表的个数为0时,直接输出为空;当输入链表的个数为奇数是,则L2中默认少一位

3.方案设计

1.数据类型设计:

typedef struct Node

{

  int elem;

  struct Node* next;

}*linklist;

2.算法设计(算法的基本思想、具体步骤,各程序模块之间的层次(调用)关系流程图等):

用函数的方式模块化完成任务,并且界面简洁,功能清晰

4.测试分析

设计测试范例(测试数据包括正确的输入、边界条件、含有错误的输入等),列出程序的测试结果(附截图),测试结果的分析与讨论。可列出测试过程中遇到的主要问题及所采用的解决措施。

5.心得

对实验设计与实现过程的回顾和分析,说明程序的改进思想、经验和体会。

实验设计中,只要思路清晰,写代码就变的清晰和容易

函数注释要写清晰,不然可能会误导自己和其他看代码的人

多文件系统使代码变得更简洁

6.附录

列出程序文件清单,及文件功能。

头文件:

linklist.h:放函数基本头文件,结构类型定义,函数声明等

源文件:

linklist.cpp:放主函数的操作

function.cpp:放函数的代码

代码注释要求:

  1. 对关键的算法实现代码有必要的注释
  2. 函数说明格式:

*****************************************************

函数名:

函数功能:

输入参数:

       类型,参数名,含义

输出参数:

       返回值,含义

文件提交要求:

将两道题目各自的完整工程(包含该工程下所有目录和文件)和此文档一起打包,以组内学生姓名作为文件名,上传提交。例如Stu1_Stu2.zip

linklist.h

#pragma once
# include <iostream>
# include <stdlib.h>
# include <stdio.h>

using namespace std;

typedef struct Node
{
	int elem;
	struct Node* next;
}*linklist;

void inlinklist(linklist& l, int n);
/********************************
函数名:inlinklist
函数功能:输入链表的值
输入参数:类型,参数名,含义
          linklist,l,链表
          int,l,输入的元素个数
输出参数:返回值,含义
          void,为空
*********************************/

void outlinklist(linklist l);
/********************************
函数名:outlinklist
函数功能:输出链表的值
输入参数:类型,参数名,含义
          linklist,l,链表
输出参数:返回值,含义
          void,为空
*********************************/

void splitlinklist(linklist& l1, linklist& l2, linklist& l3);
/********************************
函数名:splitlinklist
函数功能:把链表分开
输入参数:类型,参数名,含义
          linklist,l1 l2 l3,第一链表 第二链表 第三链表
输出参数:返回值,含义
          void,为空
*********************************/

void recursive_reverse(struct Node* head);
/********************************
函数名:recursive_reverse
函数功能:链表的就地反转
输入参数:类型,参数名,含义
          struct Node,head,链表
输出参数:返回值,含义
          void,为空
*********************************/

function.cpp

#include"linklist.h"

void inlinklist(linklist& l, int n)
{
	l = (linklist)malloc(sizeof(Node));
	l->next = NULL;
	linklist p, end;
	end = l;

	printf("请输入链表中的元素:\n");
	for (int i = 0; i < n; i++)
	{
		p = (linklist)malloc(sizeof(Node));
		scanf("%d", &p->elem);
		end->next = p;
		p->next = NULL;
		end = p;
	}
}

void outlinklist(linklist l)
{
	linklist p;
	p = l->next;

	while (p)
	{
		printf("%d ", p->elem);
		p = p->next;
	}
	printf("\n");
}

void splitlinklist(linklist& l1, linklist& l2, linklist& l3)
{
	l2 = (linklist)malloc(sizeof(Node));
	l3 = (linklist)malloc(sizeof(Node));
	linklist p, q, s;
	p = l1->next;
	q = l2;
	s = l3;
	int j = 1;

	while (p)
	{
		if (j % 2 != 0)
		{
			q->next = p;
			q = q->next;
		}
		else
		{
			s->next = p;
			s = s->next;
		}
		j++;
		p = p->next;
	}
	q->next = NULL;
	s->next = NULL;
}

void recursive_reverse(struct Node* head)
{
	if (head->next == NULL) return;

	struct Node* pre = NULL;
	struct Node* cur = head->next;
	struct Node* next;

	while (cur) {
		next = cur->next;
		cur->next = pre;
		pre = cur;
		cur = next;
	}

	head->next = pre;
}

linklist.cpp

#include"linklist.h"

int main()
{
	linklist l1, l2, l3;
	int n;

	printf("请输入链表中的元素个数:\n");
	scanf_s("%d", &n);

	inlinklist(l1, n);
	splitlinklist(l1, l2, l3);
	printf("链表L1中的元素为:\n");
	outlinklist(l2);
	recursive_reverse(l3);
	printf("链表L2中的元素为:\n");
	outlinklist(l3);

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值