一,问题描述
设有线性表(34,12,45,64,28,36,45,56),采用链式存储结构。编程实现下列有关单链表的基本操作及运算:
(1) 用表头插入法创建单链表;
(2) 用表尾插入法创建单链表;
(3) 在单链表的第i个结点前插入一个结点;
(4) 删除单链表中第i个结点;
(5) 删除单链表中指定值的结点;
(6) 删除单链表中结点值等于e的所有结点;
(7) 输出链表元素;
(8) 清空单链表。
二,基本要求
(1)链表必须带有附加表头结点,设计链表结点的存储结构;
(2)掌握单链表各种基本操作的算法设计方法和技巧,分析各算法的性能;
(3)在参考程序中的下划线处填上适当的语句或文字,完善参考程序;
(4)设计测试用例,上机调试、测试参考程序,打印测试结果,对测试结果进行分析;
(5)每完成一个步骤,必须及时输出链表中的所有元素,便于观察操作结果。
三,数据结构设计
设计单链表结点结构如下:
typedef struct LNode{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode, *LinkList;
四,算法分析与设计
(1)插入算法设计
在带头结点的单链表L中第i个结点前插入一个元素值为item的新结点。算法步骤:
- 定位指针p指向第i-1个结点;
- 若定位失败,算法结束;
- 申请新结点s,将新元素item写入s的数据域;
- 令新结点s指向p的下一个结点(即第i个结点);
- 令p结点指向新结点s。
(2)删除算法设计
在带头结点的单链表L中删除第i个结点,被删结点的元素通过参数e返回。算法步骤:
- 定位指针p指向第i-1个结点,q指向p的下一个结点(被删结点);
- 若定位失败,算法结束;
- 令p结点的指针域指向q结点的下一个结点;
- 将q结点的元素保存到参数e中;
- 释放q结点空间。
五,示例代码
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FLASE 0
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode, *LinkList;
Status CreatLinkL1(LinkList &L, int n, ElemType *E) {
//用表头插入法逆序建立带头结点的单链表
int i;
LinkList p;
L = (LinkList) malloc(sizeof(LNode));
if(!L) return ERROR;
L->next = NULL; //建立头结点,假定与元素结点结构相同
for (i = n-1; i>= 0; --i) //从后向前输入元素
{
if(!(p=(LinkList)malloc(sizeof(LNode)))) //生成新结点
return ERROR;
p->data=E[i];
p->next = L->next;