mirror of
https://github.com/kangjianwei/Data-Structure.git
synced 2026-02-07 08:52:24 +08:00
💡 【教材】 ▲02 线性表
This commit is contained in:
143
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList-mian.c
Normal file
143
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList-mian.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/***************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\01 SequenceList *
|
||||
* *
|
||||
* 内 容: 单链表顺序结构相关函数测试 *
|
||||
* *
|
||||
***************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "SequenceList.c" //**▲02 线性表**//
|
||||
|
||||
/* 测试调用的函数原型 */
|
||||
Status CmpGreater(LElemType_Sq e, LElemType_Sq data);
|
||||
//若data>e,返回TRUE,否则返回FALSE
|
||||
|
||||
void PrintElem(LElemType_Sq e);
|
||||
//测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SqList L;
|
||||
int i;
|
||||
LElemType_Sq e;
|
||||
|
||||
printf("▼1\n▲函数 InitList_Sq 测试...\n"); //1.函数InitList_Sq测试
|
||||
{
|
||||
printf("初始化顺序表 L ...\n");
|
||||
InitList_Sq(&L);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼4\n▲函数 ListEmpty_Sq 测试...\n"); //4.函数ListEmpty_Sq测试
|
||||
{
|
||||
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼10\n▲函数 ListInsert_Sq 测试...\n"); //10.函数ListInsert_Sq测试
|
||||
{
|
||||
for(i=1; i<=6; i++)
|
||||
{
|
||||
printf("作为示范,在 L 第 %d 个位置插入 \"%d\"...\n", i, 2*i);
|
||||
ListInsert_Sq(&L, i, 2*i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼12\n▲函数 ListTraverse_Sq 测试...\n"); //12.函数ListTraverse_Sq测试
|
||||
{
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_Sq(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数 ListLength_Sq 测试...\n"); //5.函数ListLength_Sq测试
|
||||
{
|
||||
i = ListLength_Sq(L);
|
||||
printf(" L 的长度为 %d \n", i);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼11\n▲函数 ListDelete_Sq 测试...\n"); //11.函数ListDelete_Sq测试
|
||||
{
|
||||
ListDelete_Sq(&L, 6, &e);
|
||||
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_Sq(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数 GetElem_Sq 测试...\n"); //6.函数GetElem_Sq测试
|
||||
{
|
||||
GetElem_Sq(L, 4, &e);
|
||||
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
|
||||
printf("▼7\n▲函数 LocateElem_Sq 测试...\n"); //7.函数LocateElem_Sq测试
|
||||
{
|
||||
i = LocateElem_Sq(L, 7, CmpGreater);
|
||||
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数 PriorElem_Sq 测试...\n"); //8.函数PriorElem_Sq测试
|
||||
{
|
||||
PriorElem_Sq(L, 6, &e);
|
||||
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼9\n▲函数 NextElem_Sq 测试...\n"); //9.函数NextElem_Sq测试
|
||||
{
|
||||
NextElem_Sq(L, 6, &e);
|
||||
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2\n▲函数 ClearList_Sq 测试...\n"); //2.函数ClearList_Sq测试
|
||||
{
|
||||
printf("清空 L 前:");
|
||||
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
ClearList_Sq(&L);
|
||||
printf("清空 L 后:");
|
||||
ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼3\n▲函数 DestroyList_Sq 测试...\n"); //3.函数DestroyList_Sq测试
|
||||
{
|
||||
printf("销毁 L 前:");
|
||||
L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
DestroyList_Sq(&L);
|
||||
printf("销毁 L 后:");
|
||||
L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status CmpGreater(LElemType_Sq e, LElemType_Sq data)
|
||||
{
|
||||
return data>e ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_Sq e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
180
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.c
Normal file
180
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/***************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\01 SequenceList *
|
||||
* *
|
||||
* 文件名: SequenceList.c *
|
||||
* *
|
||||
* 算 法: 2.3、2.4、2.5、2.6 *
|
||||
* *
|
||||
***************************************/
|
||||
|
||||
#ifndef SEQUENCELIST_C
|
||||
#define SEQUENCELIST_C
|
||||
|
||||
#include "SequenceList.h" //**▲02 线性表**//
|
||||
|
||||
/*════╗
|
||||
║算法2.3 ║
|
||||
╚════*/
|
||||
Status InitList_Sq(SqList *L)
|
||||
{
|
||||
(*L).elem = (LElemType_Sq*)malloc(LIST_INIT_SIZE*sizeof(LElemType_Sq));
|
||||
if(!(*L).elem)
|
||||
exit(OVERFLOW); //分配内存失败
|
||||
|
||||
(*L).length = 0; //初始化顺序表长度为0
|
||||
(*L).listsize = LIST_INIT_SIZE; //顺序表初始内存分配量
|
||||
|
||||
return OK; //初始化成功
|
||||
}
|
||||
|
||||
void ClearList_Sq(SqList *L)
|
||||
{
|
||||
(*L).length = 0;
|
||||
}
|
||||
|
||||
void DestroyList_Sq(SqList *L)
|
||||
{
|
||||
free((*L).elem);
|
||||
|
||||
(*L).elem = NULL; //释放内存后置空指针
|
||||
(*L).length = 0;
|
||||
(*L).listsize = 0;
|
||||
}
|
||||
|
||||
Status ListEmpty_Sq(SqList L)
|
||||
{
|
||||
return L.length==0 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
int ListLength_Sq(SqList L)
|
||||
{
|
||||
return L.length;
|
||||
}
|
||||
|
||||
Status GetElem_Sq(SqList L, int i, LElemType_Sq *e)
|
||||
{
|
||||
if(i<1 || i>L.length)
|
||||
return ERROR; //i值不合法
|
||||
else
|
||||
*e = L.elem[i-1];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*════╗
|
||||
║算法2.6 ║
|
||||
╚════*/
|
||||
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq))
|
||||
{
|
||||
int i = 1; //i的初值为第一个元素的位序
|
||||
|
||||
while(i<=L.length && !Compare(e, L.elem[i-1]))
|
||||
++i;
|
||||
|
||||
if(i<=L.length)
|
||||
return i;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
if(L.elem[0]!=cur_e) //第一个结点无前驱
|
||||
{
|
||||
while(i<L.length && L.elem[i]!=cur_e)
|
||||
++i;
|
||||
|
||||
if(i<L.length)
|
||||
{
|
||||
*pre_e = L.elem[i-1];
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while(i<L.length && L.elem[i]!=cur_e)
|
||||
++i;
|
||||
|
||||
if(i<L.length-1) //最后一个结点无后继
|
||||
{
|
||||
*next_e = L.elem[i+1];
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*════╗
|
||||
║算法2.4 ║
|
||||
╚════*/
|
||||
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e)
|
||||
{
|
||||
LElemType_Sq *newbase;
|
||||
LElemType_Sq *p, *q;
|
||||
|
||||
if(i<1 || i>(*L).length+1)
|
||||
return ERROR; //i值不合法
|
||||
|
||||
if((*L).length >= (*L).listsize) //若存储空间已满,需开辟新空间
|
||||
{
|
||||
newbase = (LElemType_Sq*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(LElemType_Sq));
|
||||
if(!newbase)
|
||||
exit(OVERFLOW);
|
||||
|
||||
(*L).elem = newbase;
|
||||
(*L).listsize += LISTINCREMENT;
|
||||
}
|
||||
|
||||
q = &(*L).elem[i-1]; //q为插入位置
|
||||
|
||||
for(p=&(*L).elem[(*L).length-1]; p>=q; --p)
|
||||
*(p+1) = *p; //插入位置及之后的元素右移
|
||||
|
||||
*q = e; //插入e
|
||||
(*L).length++; //表长增1
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*════╗
|
||||
║算法2.5 ║
|
||||
╚════*/
|
||||
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e)
|
||||
{
|
||||
LElemType_Sq *p, *q;
|
||||
|
||||
if(i<1 || i>(*L).length)
|
||||
return ERROR; //i值不合法
|
||||
|
||||
p = &(*L).elem[i-1]; //p为被删除元素的位置
|
||||
*e = *p;
|
||||
q = (*L).elem+(*L).length-1; //表尾元素位置
|
||||
|
||||
for(++p; p<=q; ++p)
|
||||
*(p-1) = *p; //被删元素之后的元素左移
|
||||
|
||||
(*L).length--; //表长减1
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ListTraverse_Sq(SqList L, void(Visit)(LElemType_Sq))
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<L.length; i++)
|
||||
Visit(L.elem[i]);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
96
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.h
Normal file
96
▲课本算法实现/▲02 线性表/01 SequenceList/SequenceList.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/***************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\01 SequenceList *
|
||||
* *
|
||||
* 文件名: SequenceList.h *
|
||||
* *
|
||||
* 内 容: 顺序表相关操作列表 *
|
||||
* *
|
||||
***************************************/
|
||||
|
||||
#ifndef SEQUENCELIST_H
|
||||
#define SEQUENCELIST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
|
||||
#define LISTINCREMENT 10 //顺序表存储空间的分配增量
|
||||
|
||||
/* 顺序表类型定义 */
|
||||
#ifndef LELEMTYPE_SQ
|
||||
#define LELEMTYPE_SQ
|
||||
typedef int LElemType_Sq;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LElemType_Sq *elem; //存储空间基址(指向第一个结点的指针)
|
||||
int length; //当前顺序表长度
|
||||
int listsize; //当前分配的存储容量
|
||||
}SqList; //顺序表0号单元正常使用
|
||||
|
||||
/* 顺序表函数列表 */
|
||||
Status InitList_Sq(SqList *L);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.3:初始化空顺序表L。┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
void ClearList_Sq(SqList *L);
|
||||
/*━━━━━━━━━┓
|
||||
┃(02)清空顺序表L。 ┃
|
||||
┗━━━━━━━━━*/
|
||||
|
||||
void DestroyList_Sq(SqList *L);
|
||||
/*━━━━━━━━━┓
|
||||
┃(03)销毁顺序表L。 ┃
|
||||
┗━━━━━━━━━*/
|
||||
|
||||
Status ListEmpty_Sq(SqList L);
|
||||
/*━━━━━━━━━━━━━┓
|
||||
┃(04)判断顺序表L是否为空。 ┃
|
||||
┗━━━━━━━━━━━━━*/
|
||||
|
||||
int ListLength_Sq(SqList L);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(05)返回顺序表L中元素个数。 ┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
Status GetElem_Sq(SqList L, int i, LElemType_Sq *e);
|
||||
/*━━━━━━━━━━━━━━━━┓
|
||||
┃(06)用e接收顺序表L中第i个元素。 ┃
|
||||
┗━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq));
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(07)算法2.6:返回顺序表L中首个与e满足Compare关系的元素位序。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e);
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(08)用pre_e接收cur_e的前驱。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e);
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(09)用next_e接收cur_e的后继。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(10)算法2.4:在顺序表L的第i个位置上插入e。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(11)算法2.5:删除顺序表L上第i个位置的元素,并用e返回。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListTraverse_Sq(SqList L, void (Visit)(LElemType_Sq));
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(12)用visit函数访问顺序表L。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
46
▲课本算法实现/▲02 线性表/02 Union/Union-main.c
Normal file
46
▲课本算法实现/▲02 线性表/02 Union/Union-main.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\02 Union *
|
||||
* *
|
||||
* 内 容: 求并集相关函数测试 *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Union.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_Sq e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SqList La, Lb;
|
||||
LElemType_Sq a[5] = {5, 2, 1, 3, 9};
|
||||
LElemType_Sq b[7] = {7, 2, 6, 9, 11, 3, 10};
|
||||
int i;
|
||||
|
||||
InitList_Sq(&La); //初始化La
|
||||
for(i=1; i<=5; i++)
|
||||
ListInsert_Sq(&La, i, a[i-1]);
|
||||
InitList_Sq(&Lb); //初始化Lb
|
||||
for(i=1; i<=7; i++)
|
||||
ListInsert_Sq(&Lb, i, b[i-1]);
|
||||
|
||||
printf("La = "); //输出La
|
||||
ListTraverse_Sq(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb = "); //输出Lb
|
||||
ListTraverse_Sq(Lb, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
printf("La = La∪Lb = "); //输出新表La的内容
|
||||
Union(&La, Lb);
|
||||
ListTraverse_Sq(La, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_Sq e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
41
▲课本算法实现/▲02 线性表/02 Union/Union.c
Normal file
41
▲课本算法实现/▲02 线性表/02 Union/Union.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\02 Union *
|
||||
* *
|
||||
* 文件名: Union.c *
|
||||
* *
|
||||
* 算 法: 2.1 *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
#ifndef UNION_C
|
||||
#define UNION_C
|
||||
|
||||
#include "Union.h" //**▲02 线性表**//
|
||||
|
||||
/*════╗
|
||||
║ 算法2.1║
|
||||
╚════*/
|
||||
void Union(SqList *La, SqList Lb)
|
||||
{
|
||||
int La_len, Lb_len;
|
||||
int i;
|
||||
LElemType_Sq e;
|
||||
|
||||
La_len = ListLength_Sq(*La); //求顺序表长度
|
||||
Lb_len = ListLength_Sq(Lb);
|
||||
|
||||
for(i=1; i<=Lb_len; i++)
|
||||
{
|
||||
GetElem_Sq(Lb, i, &e); //取Lb中第i个元素赋给e
|
||||
if(!LocateElem_Sq(*La, e, equal)) //若e不在La中则插入
|
||||
ListInsert_Sq(La, ++La_len, e);
|
||||
}
|
||||
}
|
||||
|
||||
Status equal(LElemType_Sq e1, LElemType_Sq e2)
|
||||
{
|
||||
return e1==e2 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
27
▲课本算法实现/▲02 线性表/02 Union/Union.h
Normal file
27
▲课本算法实现/▲02 线性表/02 Union/Union.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\02 Union *
|
||||
* *
|
||||
* 文件名: Union.h *
|
||||
* *
|
||||
* 内 容: 求并集相关操作列表 *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
#ifndef UNION_H
|
||||
#define UNION_H
|
||||
|
||||
#include "../01 SequenceList/SequenceList.c" //**▲02 线性表**//
|
||||
|
||||
/* 并集函数列表 */
|
||||
void Union(SqList *La, SqList Lb);
|
||||
/*━━━━━━━━━━━┓
|
||||
┃(01)算法2.1:A=A∪B。 ┃
|
||||
┗━━━━━━━━━━━*/
|
||||
|
||||
Status equal(LElemType_Sq e1, LElemType_Sq e2);
|
||||
/*━━━━━━━━━━━━┓
|
||||
┃(02)判断两元素是否相等。┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
51
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList-main.c
Normal file
51
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList-main.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/**************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\03 MergeSqList *
|
||||
* *
|
||||
* 内 容: 顺序表归并相关函数测试 *
|
||||
* *
|
||||
**************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "MergeSqList.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_Sq e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SqList La, Lb, Lc1, Lc2;
|
||||
LElemType_Sq a[4] = {3, 5, 8, 11};
|
||||
LElemType_Sq b[7] = {2, 6, 8, 9, 11, 15, 20};
|
||||
int i;
|
||||
|
||||
InitList_Sq(&La); //初始化La
|
||||
for(i=1; i<=4; i++)
|
||||
ListInsert_Sq(&La, i, a[i-1]);
|
||||
InitList_Sq(&Lb); //初始化Lb
|
||||
for(i=1; i<=7; i++)
|
||||
ListInsert_Sq(&Lb, i, b[i-1]);
|
||||
|
||||
printf("La = "); //输出La
|
||||
ListTraverse_Sq(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb = "); //输出Lb
|
||||
ListTraverse_Sq(Lb, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
MergeSqList_1(La, Lb, &Lc1); //合并A与B,算法2.6
|
||||
printf("合并La和Lb为Lc1 = "); //输出Lc1
|
||||
ListTraverse_Sq(Lc1, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
MergeSqList_2(La, Lb, &Lc2); //合并A与B,算法2.7
|
||||
printf("合并La和Lb为Lc2 = "); //输出Lc2
|
||||
ListTraverse_Sq(Lc2, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_Sq e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
97
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList.c
Normal file
97
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/**************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\03 MergeSqList *
|
||||
* *
|
||||
* 文件名: MergeSqList.c *
|
||||
* *
|
||||
* 算 法: 2.2、2.7 *
|
||||
* *
|
||||
**************************************/
|
||||
|
||||
#ifndef MERGESQLIST_C
|
||||
#define MERGESQLIST_C
|
||||
|
||||
#include "MergeSqList.h" //**▲02 线性表**//
|
||||
|
||||
/*════╗
|
||||
║ 算法2.2║
|
||||
╚════*/
|
||||
void MergeSqList_1(SqList La, SqList Lb, SqList *Lc) //调用顺序表函数进行合并
|
||||
{
|
||||
int La_len, Lb_len;
|
||||
int i, j, k;
|
||||
LElemType_Sq ai, bj;
|
||||
|
||||
i = j = 1;
|
||||
k = 0;
|
||||
|
||||
InitList_Sq(Lc); //初始化Lc
|
||||
La_len = ListLength_Sq(La); //获取La、Lb长度
|
||||
Lb_len = ListLength_Sq(Lb);
|
||||
|
||||
while(i<=La_len && j<=Lb_len) //La及Lb均未扫描完
|
||||
{
|
||||
GetElem_Sq(La, i, &ai);
|
||||
GetElem_Sq(Lb, j, &bj);
|
||||
|
||||
if(ai<=bj)
|
||||
{
|
||||
ListInsert_Sq(Lc, ++k, ai);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ListInsert_Sq(Lc, ++k, bj);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
while(i<=La_len) //表La还未扫描完
|
||||
{
|
||||
GetElem_Sq(La, i++, &ai);
|
||||
ListInsert_Sq(Lc, ++k, ai);
|
||||
}
|
||||
|
||||
while(j<=Lb_len) //表Lb还未扫描完
|
||||
{
|
||||
GetElem_Sq(Lb, j++, &bj);
|
||||
ListInsert_Sq(Lc, ++k, bj);
|
||||
}
|
||||
}
|
||||
|
||||
/*════╗
|
||||
║ 算法2.7║
|
||||
╚════*/
|
||||
void MergeSqList_2(SqList La, SqList Lb, SqList *Lc)
|
||||
{
|
||||
LElemType_Sq *pa, *pb, *pc;
|
||||
LElemType_Sq *pa_last, *pb_last;
|
||||
|
||||
pa = La.elem; //指向La第一个元素
|
||||
pb = Lb.elem; //指向Lb第一个元素
|
||||
|
||||
//不用InitList_Sq创建Lc
|
||||
(*Lc).listsize = (*Lc).length = La.length + Lb.length;
|
||||
pc = (*Lc).elem = (LElemType_Sq *)malloc((*Lc).listsize*sizeof(LElemType_Sq));
|
||||
if(!pc)
|
||||
exit(OVERFLOW);
|
||||
|
||||
pa_last = La.elem + La.length - 1; //指向La最后一个元素
|
||||
pb_last = Lb.elem + Lb.length - 1; //指向Lb最后一个元素
|
||||
|
||||
while(pa<=pa_last && pb<=pb_last) //La和Lb均未扫描完
|
||||
{
|
||||
if(*pa <= *pb)
|
||||
*pc++ = *pa++;
|
||||
else
|
||||
*pc++ = *pb++;
|
||||
}
|
||||
|
||||
while(pa <= pa_last) //表La未扫描完
|
||||
*pc++ = *pa++; //插入La的剩余元素
|
||||
|
||||
while(pb <= pb_last) //表Lb未扫描完
|
||||
*pc++ = *pb++; //插入Lb的剩余元素
|
||||
}
|
||||
|
||||
#endif
|
||||
28
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList.h
Normal file
28
▲课本算法实现/▲02 线性表/03 MergeSqList/MergeSqList.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/**************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\03 MergeSqList *
|
||||
* *
|
||||
* 文件名: MergeSqList.h *
|
||||
* *
|
||||
* 内 容: 顺序表归并相关操作列表 *
|
||||
* *
|
||||
**************************************/
|
||||
|
||||
#ifndef MERGESQLIST_H
|
||||
#define MERGESQLIST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../01 SequenceList/SequenceList.c" //**▲02 线性表**//
|
||||
|
||||
/* 顺序表归并函数列表 */
|
||||
void MergeSqList_1(SqList La, SqList Lb, SqList *Lc);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.2:求C=A+B,A,B,C均为非递减序列 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void MergeSqList_2(SqList La, SqList Lb, SqList *Lc);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(02)算法2.7:求C=A+B,A,B,C均为非递减序列 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
164
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList-mian.c
Normal file
164
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList-mian.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*******************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
|
||||
* *
|
||||
* 内 容: 单链表相关函数测试 *
|
||||
* *
|
||||
*******************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "SinglyLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status CmpGreater(LElemType_L e, LElemType_L data); //判断data是否大于e //若data大于e,返回TRUE
|
||||
void PrintElem(LElemType_L e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
LinkList L;
|
||||
int i;
|
||||
LElemType_L e;
|
||||
|
||||
printf("▼1\n▲函数 InitList_L 测试...\n"); //1.函数InitList_L测试
|
||||
{
|
||||
printf("初始化单链表 L ...\n");
|
||||
InitList_L(&L);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼4\n▲函数 ListEmpty_L 测试...\n"); //4.函数ListEmpty_L测试
|
||||
{
|
||||
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼10\n▲函数 ListInsert_L 测试...\n"); //10.函数ListInsert_L测试
|
||||
{
|
||||
for(i=1; i<=6; i++)
|
||||
{
|
||||
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
|
||||
ListInsert_L(L, i, 2*i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼12\n▲函数 ListTraverse_L 测试...\n"); //12.函数ListTraverse_L测试
|
||||
{
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_L(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数 ListLength_L 测试...\n"); //5.函数ListLength_L测试
|
||||
{
|
||||
printf(" L 的长度为 %d \n", ListLength_L(L));
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼11\n▲函数 ListDelete_L 测试...\n"); //11.函数ListDelete_L测试
|
||||
{
|
||||
ListDelete_L(L, 6, &e);
|
||||
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_L(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数 GetElem_L 测试...\n"); //6.函数GetElem_L测试
|
||||
{
|
||||
GetElem_L(L, 4, &e);
|
||||
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼7\n▲函数 LocateElem_L 测试...\n"); //7.函数LocateElem_L测试
|
||||
{
|
||||
i = LocateElem_L(L, 13, CmpGreater);
|
||||
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数 PriorElem_L 测试...\n"); //8.函数PriorElem_L测试
|
||||
{
|
||||
PriorElem_L(L, 6, &e);
|
||||
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼9\n▲函数 NextElem_L 测试...\n"); //9.函数NextElem_L测试
|
||||
{
|
||||
NextElem_L(L, 6, &e);
|
||||
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2\n▲函数 ClearList_L 测试...\n"); //2.函数ClearList_L测试
|
||||
{
|
||||
printf("清空 L 前:");
|
||||
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
ClearList_L(L);
|
||||
printf("清空 L 后:");
|
||||
ListEmpty_L(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼3\n▲函数 DestroyList_L 测试...\n"); //3.函数DestroyList_L测试
|
||||
{
|
||||
printf("销毁 L 前:");
|
||||
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
DestroyList_L(&L);
|
||||
printf("销毁 L 后:");
|
||||
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼13\n▲函数 CreateList_HL 测试...\n"); //13.函数CreateList_HL测试
|
||||
{
|
||||
FILE *fp;
|
||||
LinkList L;
|
||||
printf("头插法建立单链表 L = ");
|
||||
fp = fopen("TestData_HL.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_HL(fp, &L, 5);
|
||||
fclose(fp);
|
||||
ListTraverse_L(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼14\n▲函数 CreateList_TL 测试...\n"); //14.函数CreateList_TL测试
|
||||
{
|
||||
FILE *fp;
|
||||
LinkList L;
|
||||
printf("尾插法建立单链表 L = ");
|
||||
fp = fopen("TestData_TL.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_TL(fp, &L, 5);
|
||||
fclose(fp);
|
||||
ListTraverse_L(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status CmpGreater(LElemType_L e, LElemType_L data)
|
||||
{
|
||||
return data>e ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_L e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
337
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.c
Normal file
337
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/*******************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
|
||||
* *
|
||||
* 文件名: SinglyLinkedList.c *
|
||||
* *
|
||||
* 算 法: 2.8、2.9、2.10、2.11 *
|
||||
* *
|
||||
*******************************************/
|
||||
|
||||
#ifndef SINGLYLINKEDLIST_C
|
||||
#define SINGLYLINKEDLIST_C
|
||||
|
||||
#include "SinglyLinkedList.h" //**▲02 线性表**//
|
||||
|
||||
Status InitList_L(LinkList *L)
|
||||
{
|
||||
(*L) = (LinkList)malloc(sizeof(LNode));
|
||||
if(!(*L))
|
||||
exit(OVERFLOW);
|
||||
(*L)->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ClearList_L(LinkList L) //保留头结点
|
||||
{
|
||||
LinkList pre, p;
|
||||
|
||||
if(!L)
|
||||
return ERROR;
|
||||
|
||||
pre = L->next;
|
||||
|
||||
while(pre)
|
||||
{
|
||||
p = pre->next;
|
||||
free(pre);
|
||||
pre = p;
|
||||
}
|
||||
|
||||
L->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DestroyList_L(LinkList *L) //销毁所有结点
|
||||
{
|
||||
LinkList p = *L;
|
||||
|
||||
while(p)
|
||||
{
|
||||
p = (*L)->next;
|
||||
free(*L);
|
||||
(*L) = p;
|
||||
}
|
||||
}
|
||||
|
||||
Status ListEmpty_L(LinkList L)
|
||||
{
|
||||
if(L!=NULL && L->next==NULL) //链表存在且只有头结点
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int ListLength_L(LinkList L)
|
||||
{
|
||||
LinkList p;
|
||||
int i;
|
||||
|
||||
if(L)
|
||||
{
|
||||
i = 0;
|
||||
p = L->next;
|
||||
while(p)
|
||||
{
|
||||
i++;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*════╗
|
||||
║ 算法2.8║
|
||||
╚════*/
|
||||
Status GetElem_L(LinkList L, int i, LElemType_L *e)
|
||||
{
|
||||
int j;
|
||||
LinkList p = L->next;
|
||||
|
||||
j = 1;
|
||||
p = L->next;
|
||||
|
||||
while(p && j<i) //p不为空且还未到达i处
|
||||
{
|
||||
j++;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(!p || j>i) //第i个元素不存在
|
||||
return ERROR;
|
||||
|
||||
*e = p->data;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int LocateElem_L(LinkList L, LElemType_L e, Status(Compare)(LElemType_L, LElemType_L))
|
||||
{
|
||||
int i;
|
||||
LinkList p;
|
||||
|
||||
i = -1; //L不存在时返回-1
|
||||
|
||||
if(L)
|
||||
{
|
||||
i = 0;
|
||||
p = L->next;
|
||||
|
||||
while(p)
|
||||
{
|
||||
i++;
|
||||
|
||||
if(!Compare(e, p->data))
|
||||
{
|
||||
p = p->next;
|
||||
if(p==NULL) //失配时已经是最后一个结点
|
||||
i++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* 银行排队算法中,此处两个函数不能直接使用,原因是结构不能直接比较 */
|
||||
#ifndef BANKQUEUING_C
|
||||
Status PriorElem_L(LinkList L, LElemType_L cur_e, LElemType_L *pre_e)
|
||||
{
|
||||
LinkList p, suc;
|
||||
|
||||
if(L)
|
||||
{
|
||||
p = L->next;
|
||||
|
||||
if(p->data!=cur_e) //第一个结点无前驱
|
||||
{
|
||||
while(p->next) //若p结点有后继
|
||||
{
|
||||
suc = p->next; //suc指向p的后继
|
||||
if(suc->data==cur_e)
|
||||
{
|
||||
*pre_e = p->data;
|
||||
return OK;
|
||||
}
|
||||
p = suc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status NextElem_L(LinkList L, LElemType_L cur_e, LElemType_L *next_e)
|
||||
{
|
||||
LinkList p, suc;
|
||||
|
||||
if(L)
|
||||
{
|
||||
p = L->next;
|
||||
|
||||
while(p && p->next)
|
||||
{
|
||||
suc = p->next;
|
||||
|
||||
if(suc && p->data==cur_e)
|
||||
{
|
||||
*next_e = suc->data;
|
||||
return OK;
|
||||
}
|
||||
|
||||
if(suc)
|
||||
p = suc;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*════╗
|
||||
║ 算法2.9║
|
||||
╚════*/
|
||||
Status ListInsert_L(LinkList L, int i, LElemType_L e)
|
||||
{
|
||||
LinkList p, s;
|
||||
int j;
|
||||
|
||||
p = L;
|
||||
j = 0;
|
||||
|
||||
while(p && j<i-1) //寻找第i-1个结点
|
||||
{
|
||||
p = p->next;
|
||||
++j;
|
||||
}
|
||||
|
||||
if(!p || j>i-1)
|
||||
return ERROR;
|
||||
|
||||
s = (LinkList)malloc(sizeof(LNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = e;
|
||||
s->next = p->next;
|
||||
p->next = s;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.10 ║
|
||||
╚═════*/
|
||||
Status ListDelete_L(LinkList L, int i, LElemType_L *e)
|
||||
{
|
||||
LinkList pre, p;
|
||||
int j;
|
||||
|
||||
pre = L;
|
||||
j = 1;
|
||||
|
||||
while(pre->next && j<i) //寻找第i个结点,并令pre指向其前驱
|
||||
{
|
||||
pre = pre->next;
|
||||
++j;
|
||||
}
|
||||
|
||||
if(!pre->next || j>i) //删除位置不合理
|
||||
return ERROR;
|
||||
|
||||
p = pre->next;
|
||||
pre->next = p->next;
|
||||
*e = p->data;
|
||||
free(p);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ListTraverse_L(LinkList L, void(Visit)(LElemType_L))
|
||||
{
|
||||
LinkList p;
|
||||
|
||||
if(!L)
|
||||
return ERROR;
|
||||
else
|
||||
p = L->next;
|
||||
|
||||
while(p)
|
||||
{
|
||||
Visit(p->data);
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.11 ║
|
||||
╚═════*/
|
||||
Status CreateList_HL(FILE *fp, LinkList *L, int n)
|
||||
{
|
||||
int i;
|
||||
LinkList p;
|
||||
LElemType_L tmp;
|
||||
|
||||
*L = (LinkList)malloc(sizeof(LNode));
|
||||
if(!(*L))
|
||||
exit(OVERFLOW);
|
||||
(*L)->next = NULL; //建立头结点
|
||||
|
||||
for(i=1; i<=n; ++i)
|
||||
{
|
||||
if(Scanf(fp, "%d", &tmp)==1)
|
||||
{
|
||||
p = (LinkList)malloc(sizeof(LNode));
|
||||
if(!p)
|
||||
exit(OVERFLOW);
|
||||
p->data = tmp; //录入数据
|
||||
p->next = (*L)->next;
|
||||
(*L)->next = p;
|
||||
}
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status CreateList_TL(FILE *fp, LinkList *L, int n)
|
||||
{
|
||||
int i;
|
||||
LinkList p, q;
|
||||
LElemType_L tmp;
|
||||
|
||||
*L = (LinkList)malloc(sizeof(LNode));
|
||||
if(!(*L))
|
||||
exit(OVERFLOW);
|
||||
(*L)->next = NULL;
|
||||
|
||||
for(i=1,q=*L; i<=n; ++i)
|
||||
{
|
||||
if(Scanf(fp, "%d", &tmp)==1)
|
||||
{
|
||||
p = (LinkList)malloc(sizeof(LNode));
|
||||
if(!p)
|
||||
exit(OVERFLOW);
|
||||
p->data = tmp; //录入数据
|
||||
q->next = p;
|
||||
q = q->next;
|
||||
}
|
||||
else
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
q->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
103
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.h
Normal file
103
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/SinglyLinkedList.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*******************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\04 SinglyLinkedList *
|
||||
* *
|
||||
* 文件名: SinglyLinkedList.h *
|
||||
* *
|
||||
* 内 容: 单链表相关操作列表 *
|
||||
* *
|
||||
*******************************************/
|
||||
|
||||
#ifndef SINGLYLINKEDLIST_H
|
||||
#define SINGLYLINKEDLIST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
|
||||
|
||||
/* 单链表类型定义 */
|
||||
#ifndef BANKQUEUING_H /*后续的模拟银行排队算法中,此类型需要重新定义*/
|
||||
typedef int LElemType_L;
|
||||
|
||||
/* 单链表结构体 */
|
||||
typedef struct LNode
|
||||
{
|
||||
LElemType_L data;
|
||||
struct LNode* next;
|
||||
}LNode;
|
||||
typedef LNode* LinkList; //指向单链表结点的指针
|
||||
#endif
|
||||
|
||||
/* 单链表(带头结点)函数列表 */
|
||||
Status InitList_L(LinkList *L);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(01)初始化单链表L。 ┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
Status ClearList_L(LinkList L);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(02)置空单链表L,头结点保留。 ┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
void DestroyList_L(LinkList *L);
|
||||
/*━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(03)销毁单链表L,连同通结点一起销毁。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListEmpty_L(LinkList L);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(04)判断单链表L是否为空。 ┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
int ListLength_L(LinkList L);
|
||||
/*━━━━━━━━━━━━┓
|
||||
┃(05)返回单链表L元素个数 ┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
Status GetElem_L(LinkList L, int i, LElemType_L *e);
|
||||
/*━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(06)算法2.8:用e接收单链表L中第i个元素┃
|
||||
┗━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int LocateElem_L(LinkList L, LElemType_L e, Status(Compare)(LElemType_L, LElemType_L));
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(07)返回单链表L中第一个与e满足Compare关系的元素位序。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status PriorElem_L(LinkList L, LElemType_L cur_e, LElemType_L *pre_e);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(08)用pre_e接收cur_e的前驱。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
Status NextElem_L(LinkList L, LElemType_L cur_e, LElemType_L *next_e);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(09)用next_e接收cur_e的后继。 ┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListInsert_L(LinkList L, int i, LElemType_L e);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(10)算法2.9:在单链表L第i个位置之前插入e。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListDelete_L(LinkList L, int i, LElemType_L *e);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(11)算法2.10:删除单链表L第i个位置的值,并用e接收。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListTraverse_L(LinkList L, void(Visit)(LElemType_L));
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(12)用Visit函数访问单链表L。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
Status CreateList_HL(FILE *fp, LinkList *L, int n);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(13)算法2.11:头插法建立单链表L(逆序输入)。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status CreateList_TL(FILE *fp, LinkList *L, int n);
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(14)尾插法建立单链表L(顺序输入)。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
1
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/TestData_HL.txt
Normal file
1
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/TestData_HL.txt
Normal file
@@ -0,0 +1 @@
|
||||
降序:9 7 5 3 1
|
||||
1
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/TestData_TL.txt
Normal file
1
▲课本算法实现/▲02 线性表/04 SinglyLinkedList/TestData_TL.txt
Normal file
@@ -0,0 +1 @@
|
||||
升序:2 4 6 8 10
|
||||
50
▲课本算法实现/▲02 线性表/05 MergeList/MergeList-main.c
Normal file
50
▲课本算法实现/▲02 线性表/05 MergeList/MergeList-main.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\05 MergeList *
|
||||
* *
|
||||
* 内 容: 单链表归并相关函数测试 *
|
||||
* *
|
||||
************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "MergeList.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_L e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
LinkList La, Lb, Lc;
|
||||
int m;
|
||||
|
||||
m = 5;
|
||||
|
||||
printf("作为示例,La长度设定为 %d ,Lb设定为 %d ,创建La和Lb...\n", m, m);
|
||||
fp = fopen("TestData_HL.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_HL(fp, &La, m);
|
||||
fclose(fp);
|
||||
fp = fopen("TestData_TL.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_TL(fp, &Lb, m);
|
||||
fclose(fp);
|
||||
|
||||
printf("La = ");
|
||||
ListTraverse_L(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb = ");
|
||||
ListTraverse_L(Lb, PrintElem);
|
||||
printf("\n\n");
|
||||
PressEnter;
|
||||
|
||||
MergeList_L(La, &Lb, &Lc);
|
||||
printf("合并La和Lb为Lc = ");
|
||||
ListTraverse_L(Lc, PrintElem);
|
||||
printf("\n\n");
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_L e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
49
▲课本算法实现/▲02 线性表/05 MergeList/MergeList.c
Normal file
49
▲课本算法实现/▲02 线性表/05 MergeList/MergeList.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\05 MergeList *
|
||||
* *
|
||||
* 文件名: MergeList.c *
|
||||
* *
|
||||
* 算 法: 2.12 *
|
||||
* *
|
||||
************************************/
|
||||
|
||||
#ifndef MERGELIST_C
|
||||
#define MERGELIST_C
|
||||
|
||||
#include "MergeList.h" //**▲02 线性表**//
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.12 ║
|
||||
╚═════*/
|
||||
void MergeList_L(LinkList La, LinkList *Lb, LinkList *Lc)
|
||||
{ //指针Lb,Lc要改变,故形参是指向指针的指针
|
||||
LinkList pa, pb, pc;
|
||||
|
||||
pa = La->next;
|
||||
pb = (*Lb)->next;
|
||||
pc = *Lc = La; //用La的头结点作为Lc的头结点
|
||||
|
||||
while(pa && pb)
|
||||
{
|
||||
if(pa->data <= pb->data)
|
||||
{
|
||||
pc->next = pa;
|
||||
pc = pa;
|
||||
pa = pa->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
pc->next = pb;
|
||||
pc = pb;
|
||||
pb = pb->next;
|
||||
}
|
||||
}
|
||||
|
||||
pc->next = pa ? pa : pb; //插入剩余段
|
||||
|
||||
free(*Lb); //释放Lb的头结点
|
||||
*Lb = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
24
▲课本算法实现/▲02 线性表/05 MergeList/MergeList.h
Normal file
24
▲课本算法实现/▲02 线性表/05 MergeList/MergeList.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\05 MergeList *
|
||||
* *
|
||||
* 文件名: MergeList.h *
|
||||
* *
|
||||
* 内 容: 单链表归并相关操作列表 *
|
||||
* *
|
||||
************************************/
|
||||
|
||||
#ifndef MERGELIST_H
|
||||
#define MERGELIST_H
|
||||
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
#include "../04 SinglyLinkedList/SinglyLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 单链表归并函数列表 */
|
||||
void MergeList_L(LinkList La, LinkList *Lb, LinkList *Lc);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.12:C=A+B,且保持元素相对位置不变。 ┃
|
||||
┃ Lc利用La的头结点,Lb中结点均插入新链表Lc中。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
1
▲课本算法实现/▲02 线性表/05 MergeList/TestData_HL.txt
Normal file
1
▲课本算法实现/▲02 线性表/05 MergeList/TestData_HL.txt
Normal file
@@ -0,0 +1 @@
|
||||
降序:9 7 5 3 1
|
||||
1
▲课本算法实现/▲02 线性表/05 MergeList/TestData_TL.txt
Normal file
1
▲课本算法实现/▲02 线性表/05 MergeList/TestData_TL.txt
Normal file
@@ -0,0 +1 @@
|
||||
升序:2 4 6 8 10
|
||||
136
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList-mian.c
Normal file
136
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList-mian.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 内 容: 静态链表相关函数测试 *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "StaticLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_S e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SLinkList H;
|
||||
LElemType_S e;
|
||||
int i;
|
||||
|
||||
printf("▼1\n▲函数InitSpace_SL测试...\n"); //1.函数InitSpace_SL测试
|
||||
{
|
||||
printf("初始化静态链表的备用空间 SPACE ...\n");
|
||||
InitSpace_SL();
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2、4\n▲函数Malloc_SL、InitList_SL测试...\n");//4.函数Malloc_SL、InitList_SL测试
|
||||
{
|
||||
printf("初始化静态链表 H ,用Malloc_SL申请空间...\n");
|
||||
InitList_SL(&H);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼7\n▲函数ListEmpty_SL测试...\n"); //7.函数ListEmpty_SL测试
|
||||
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
|
||||
printf("\n");
|
||||
PressEnter;
|
||||
|
||||
printf("▼13\n▲函数ListInsert_SL测试...\n"); //13.函数ListInsert_SL测试
|
||||
{
|
||||
for(i=1; i<=6; i++)
|
||||
{
|
||||
printf("在 H 第 %d 个位置插入\"%d\" ...\n", i, 2*i);
|
||||
ListInsert_SL(H, i, 2*i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼15\n▲函数ListTraverse_SL测试...\n"); //15.函数ListTraverse_SL测试
|
||||
{
|
||||
printf(" H 中的元素为:H = ");
|
||||
ListTraverse_SL(H, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数ListLength_SL测试...\n"); //8.函数ListLength_SL测试
|
||||
{
|
||||
printf(" H 的长度为 %d \n", ListLength_SL(H));
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼3、14\n▲函数Free_SL、ListDelete_SL测试...\n");//3、14.函数Free_SL、ListDelete_SL测试
|
||||
{
|
||||
ListDelete_SL(H, 6, &e);
|
||||
printf("删除 H 中第 6 个元素 \"%d\" ,用Free_SL释放空间...\n", e);
|
||||
printf(" H 的元素为:H = ");
|
||||
ListTraverse_SL(H, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼9\n▲函数GetElem_SL测试...\n"); //9.函数GetElem_SL测试
|
||||
{
|
||||
GetElem_SL(H, 4, &e);
|
||||
printf(" H 中第 4 个位置的元素为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼10\n▲函数LocateElem_SL测试...\n"); //10.函数LocateElem_SL测试
|
||||
{
|
||||
printf("元素 \"8\" 在 H 中的位序为 %d \n", LocateElem_SL(H, 8));
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼11\n▲函数PriorElem_SL测试...\n"); //11.函数PriorElem_SL测试
|
||||
{
|
||||
PriorElem_SL(H, 6, &e);
|
||||
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼12\n▲函数NextElem_SL测试...\n"); //12.函数NextElem_SL测试
|
||||
{
|
||||
NextElem_SL(H, 6, &e);
|
||||
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数ClearList_SL测试...\n"); //5.函数ClearList_SL测试
|
||||
{
|
||||
printf("清空 H 前:");
|
||||
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
|
||||
ClearList_SL(H);
|
||||
printf("清空 H 后:");
|
||||
ListEmpty_SL(H) ? printf(" H 为空!!\n") : printf(" H 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数DestroyList_SL测试...\n"); //6.函数DestroyList_SL测试
|
||||
{
|
||||
printf("销毁 H 前:");
|
||||
H ? printf(" H 存在!\n") : printf(" H 不存在!!\n");
|
||||
DestroyList_SL(&H);
|
||||
printf("销毁 H 后:");
|
||||
H ? printf(" H 存在!\n") : printf(" H 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_S e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
307
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList.c
Normal file
307
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList.c
Normal file
@@ -0,0 +1,307 @@
|
||||
/**********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 文件名: StaticLinkedList.c *
|
||||
* *
|
||||
* 算 法: 2.13、2.14、2.15、2.16 *
|
||||
* *
|
||||
**********************************/
|
||||
|
||||
#ifndef STATICLINKEDLIST_C
|
||||
#define STATICLINKEDLIST_C
|
||||
|
||||
#include "StaticLinkedList.h" //**▲02 线性表**//
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.14 ║
|
||||
╚═════*/
|
||||
void InitSpace_SL() //首先初始化备用空间
|
||||
{
|
||||
int i; //0号单元做备用空间的起始结点
|
||||
|
||||
for(i=0; i<MAXSIZE-1; i++) //各空间结点首尾相接
|
||||
SPACE[i].cur = i + 1;
|
||||
|
||||
SPACE[MAXSIZE-1].cur = 0;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.15 ║
|
||||
╚═════*/
|
||||
int Malloc_SL() //从备用空间申请结点空间
|
||||
{
|
||||
int i;
|
||||
|
||||
i = SPACE[0].cur;
|
||||
|
||||
if(SPACE[0].cur)
|
||||
{
|
||||
SPACE[0].cur = SPACE[i].cur; //将申请到的空间从备用空间中删去
|
||||
return i; //返回新申请结点下标
|
||||
}
|
||||
else
|
||||
return 0; //申请失败返回0
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.16 ║
|
||||
╚═════*/
|
||||
void Free_SL(int k) //回收k结点空间
|
||||
{
|
||||
SPACE[k].cur = SPACE[0].cur;
|
||||
SPACE[0].cur = k;
|
||||
}
|
||||
|
||||
Status InitList_SL(SLinkList *H) //H为头结点指针
|
||||
{
|
||||
*H = Malloc_SL(); //创建头结点
|
||||
if(!(*H))
|
||||
exit(OVERFLOW); //“内存”已满
|
||||
|
||||
SPACE[*H].cur = 0; //头结点游标置为0
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ClearList_SL(SLinkList H)
|
||||
{
|
||||
int p, q;
|
||||
|
||||
if(!H)
|
||||
return ERROR;
|
||||
|
||||
p = SPACE[H].cur; //p指向第一个结点
|
||||
|
||||
while(p) //从链表首结点开始删除
|
||||
{
|
||||
SPACE[H].cur = SPACE[p].cur;
|
||||
Free_SL(p);
|
||||
p = SPACE[H].cur;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DestroyList_SL(SLinkList *H)
|
||||
{
|
||||
ClearList_SL(*H); //清空静态链表
|
||||
|
||||
Free_SL(*H); //释放头结点
|
||||
*H = 0;
|
||||
}
|
||||
|
||||
Status ListEmpty_SL(SLinkList H)
|
||||
{
|
||||
if(H && !SPACE[H].cur) //只有头结点
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int ListLength_SL(SLinkList H)
|
||||
{
|
||||
int count; //计数器
|
||||
int p;
|
||||
|
||||
if(!H)
|
||||
exit(OVERFLOW);
|
||||
|
||||
count = 0;
|
||||
p = SPACE[H].cur;
|
||||
|
||||
while(p)
|
||||
{
|
||||
count++;
|
||||
p = SPACE[p].cur;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
Status GetElem_SL(SLinkList H, int i, LElemType_S *e)
|
||||
{
|
||||
int count, p;
|
||||
|
||||
if(!H || i<1 || i>MAXSIZE-2)
|
||||
return ERROR;
|
||||
|
||||
count = 0;
|
||||
p = SPACE[H].cur;
|
||||
|
||||
while(p)
|
||||
{
|
||||
count++;
|
||||
|
||||
if(count==i)
|
||||
{
|
||||
*e = SPACE[p].data;
|
||||
return OK;
|
||||
}
|
||||
|
||||
p = SPACE[p].cur;
|
||||
}
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.13 ║
|
||||
╚═════*/
|
||||
int LocateElem_SL(SLinkList H, LElemType_S e)
|
||||
{
|
||||
int k, count;
|
||||
|
||||
count = 1;
|
||||
if(H && SPACE[H].cur)
|
||||
{
|
||||
k = SPACE[H].cur;
|
||||
|
||||
while(k && SPACE[k].data!=e)
|
||||
{
|
||||
count++;
|
||||
k = SPACE[k].cur;
|
||||
}
|
||||
|
||||
if(k)
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status PriorElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *pre_e)
|
||||
{
|
||||
int p, q;
|
||||
|
||||
if(H)
|
||||
{
|
||||
p = SPACE[H].cur;
|
||||
|
||||
if(p && SPACE[p].data!=cur_e)
|
||||
{
|
||||
q = SPACE[p].cur;
|
||||
|
||||
while(q && SPACE[q].data!=cur_e)
|
||||
{
|
||||
p = q;
|
||||
q= SPACE[q].cur;
|
||||
}
|
||||
|
||||
if(q) //找到了cur_e
|
||||
{
|
||||
*pre_e = SPACE[p].data;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status NextElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *next_e)
|
||||
{
|
||||
int p;
|
||||
|
||||
if(H)
|
||||
{
|
||||
p = SPACE[H].cur;
|
||||
|
||||
while(p && SPACE[p].data!=cur_e)
|
||||
p = SPACE[p].cur;
|
||||
|
||||
if(p && SPACE[p].cur) //找到了cur_e且不是最后一个结点
|
||||
{
|
||||
p = SPACE[p].cur;
|
||||
*next_e = SPACE[p].data;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status ListInsert_SL(SLinkList H, int i, LElemType_S e)
|
||||
{
|
||||
int count, k, p;
|
||||
|
||||
if(!H) //链表不存在
|
||||
return ERROR;
|
||||
|
||||
if(i>0)
|
||||
{
|
||||
count = 0;
|
||||
k = H; //k指向头结点
|
||||
|
||||
while(k && count<i-1) //寻找插入位置的前一个位置
|
||||
{
|
||||
count++;
|
||||
k = SPACE[k].cur;
|
||||
}
|
||||
|
||||
if(k) //找到了第i-1个元素的位置
|
||||
{
|
||||
p = Malloc_SL();
|
||||
if(!p) //申请空间失败
|
||||
return ERROR;
|
||||
|
||||
SPACE[p].data = e; //插入元素e
|
||||
SPACE[p].cur = SPACE[k].cur;
|
||||
SPACE[k].cur = p;
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status ListDelete_SL(SLinkList H, int i, LElemType_S *e)
|
||||
{
|
||||
int count, k, p;
|
||||
|
||||
if(!H) //链表不存在
|
||||
return ERROR;
|
||||
|
||||
if(i>0)
|
||||
{
|
||||
count = 0;
|
||||
k = H; //k指向头结点
|
||||
|
||||
while(k && count<i-1) //寻找插入位置的前一个位置
|
||||
{
|
||||
count++;
|
||||
k = SPACE[k].cur;
|
||||
}
|
||||
|
||||
if(k && SPACE[k].cur) //找到了第i-1个元素的位置且不是最后一个元素
|
||||
{
|
||||
p = SPACE[k].cur; //p指向要被删除的结点
|
||||
*e = SPACE[p].data;
|
||||
SPACE[k].cur = SPACE[p].cur;
|
||||
Free_SL(p);
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status ListTraverse_SL(SLinkList H, void(Visit)(LElemType_S))
|
||||
{
|
||||
int p;
|
||||
|
||||
if(!H)
|
||||
return ERROR; //静态链表不存在或为空
|
||||
|
||||
p = SPACE[H].cur;
|
||||
|
||||
while(p)
|
||||
{
|
||||
Visit(SPACE[p].data);
|
||||
p = SPACE[p].cur;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
115
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList.h
Normal file
115
▲课本算法实现/▲02 线性表/06 StaticLinkedList/StaticLinkedList.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/********************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 文件名: StaticLinkedList.h *
|
||||
* *
|
||||
* 内 容: 静态链表相关操作列表 *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
★备注: ┃
|
||||
★1.为操作方便,特为申请到的空间段设一“头结点”。┃
|
||||
★2.模拟系统动态申请空间过程。 ┃
|
||||
★3.个别操作会与严蔚敏数据结构课本有所差异。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#ifndef STATICLINKEDLIST_H
|
||||
#define STATICLINKEDLIST_H
|
||||
|
||||
#include <stdlib.h> ////提供malloc、realloc、free、exit原型
|
||||
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define MAXSIZE 1000 //静态链表的最大长度
|
||||
|
||||
/* 静态链表类型定义 */
|
||||
typedef int SLinkList; //静态链表类型
|
||||
typedef int LElemType_S;
|
||||
typedef struct
|
||||
{
|
||||
LElemType_S data;
|
||||
int cur; //cur是游标,做指针用,区别于数组下标
|
||||
}Component[MAXSIZE]; //链表空间类型
|
||||
|
||||
/* 全局变量 */
|
||||
Component SPACE; //静态链表空间
|
||||
|
||||
/* 静态链表函数列表 */
|
||||
void InitSpace_SL();
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.14:将一维数组SPACE中各分量链成一个大的备用空间。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int Malloc_SL();
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(02)算法2.15:为插入数据申请空间。┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void Free_SL(int k);
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(03)算法2.16:将下标为k的空闲结点回收。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int InitList_SL(SLinkList *H);
|
||||
/*━━━━━━━━━━━━━━━━┓
|
||||
┃(04)初始化静态链表,建立头结点。┃
|
||||
┗━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ClearList_SL(SLinkList H);
|
||||
/*━━━━━┓
|
||||
┃(05)置空。┃
|
||||
┗━━━━━*/
|
||||
|
||||
void DestroyList_SL(SLinkList *H);
|
||||
/*━━━━━┓
|
||||
┃(06)销毁。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status ListEmpty_SL(SLinkList H);
|
||||
/*━━━━━┓
|
||||
┃(07)判空。┃
|
||||
┗━━━━━*/
|
||||
|
||||
int ListLength_SL(SLinkList H);
|
||||
/*━━━━━┓
|
||||
┃(08)求长。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status GetElem_SL(SLinkList H, int i, LElemType_S *e);
|
||||
/*━━━━━┓
|
||||
┃(09)取值。┃
|
||||
┗━━━━━*/
|
||||
|
||||
int LocateElem_SL(SLinkList H, LElemType_S e);
|
||||
/*━━━━━━━━━━━━━━━━┓
|
||||
┃(10)算法2.13:返回元素e的位序。 ┃
|
||||
┗━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status PriorElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *pre_e);
|
||||
/*━━━━━┓
|
||||
┃(11)前驱。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status NextElem_SL(SLinkList H, LElemType_S cur_e, LElemType_S *next_e);
|
||||
/*━━━━━┓
|
||||
┃(12)后继。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status ListInsert_SL(SLinkList H, int i, LElemType_S e);
|
||||
/*━━━━━┓
|
||||
┃(13)插入。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status ListDelete_SL(SLinkList H, int i, LElemType_S *e);
|
||||
/*━━━━━┓
|
||||
┃(14)删除。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status ListTraverse_SL(SLinkList H, void(Visit)(LElemType_S));
|
||||
/*━━━━━┓
|
||||
┃(15)访问。┃
|
||||
┗━━━━━*/
|
||||
|
||||
#endif
|
||||
51
▲课本算法实现/▲02 线性表/07 Difference/Difference-main.c
Normal file
51
▲课本算法实现/▲02 线性表/07 Difference/Difference-main.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\07 Difference *
|
||||
* *
|
||||
* 内 容: 算法2.17相关函数测试 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Difference.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_S e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SLinkList S;
|
||||
FILE *fp;
|
||||
int len_A, len_B, i;
|
||||
LElemType_S A[100], B[100];
|
||||
|
||||
len_A = 3;
|
||||
len_B = 5;
|
||||
|
||||
fp = fopen("TestData.txt", "r"); //文件指针,指向数据源
|
||||
for(i=0; i<len_A; i++) //集合A
|
||||
Scanf(fp, "%d", &A[i]);
|
||||
for(i=0; i<len_B; i++) //集合B
|
||||
Scanf(fp, "%d", &B[i]);
|
||||
fclose(fp);
|
||||
|
||||
printf("A = ");
|
||||
for(i=0; i<len_A; i++)
|
||||
PrintElem(A[i]);
|
||||
printf("\n");
|
||||
printf("B = ");
|
||||
for(i=0; i<len_B; i++)
|
||||
PrintElem(B[i]);
|
||||
printf("\n\n");
|
||||
|
||||
printf("S = (A-B)∪(B-A) = ");
|
||||
difference(&S, A, len_A, B, len_B);
|
||||
ListTraverse_SL(S, PrintElem);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_S e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
67
▲课本算法实现/▲02 线性表/07 Difference/Difference.c
Normal file
67
▲课本算法实现/▲02 线性表/07 Difference/Difference.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\07 Difference *
|
||||
* *
|
||||
* 文件名: Difference.c *
|
||||
* *
|
||||
* 算 法: 2.17 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#ifndef DIFFERENCE_C
|
||||
#define DIFFERENCE_C
|
||||
|
||||
#include "Difference.h" //**▲02 线性表**//
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.17 ║
|
||||
╚═════*/
|
||||
void difference(SLinkList *S, LElemType_S A[], int len_A, LElemType_S B[], int len_B)
|
||||
{
|
||||
int i, j;
|
||||
int r, p, k;
|
||||
LElemType_S b;
|
||||
|
||||
InitSpace_SL();
|
||||
*S = Malloc_SL(); //头结点
|
||||
r = *S; //r指向S的当前最后结点(尾指针)
|
||||
SPACE[r].cur = 0;
|
||||
|
||||
for(j=0; j<len_A; j++) //建立集合A的链表
|
||||
{
|
||||
i = Malloc_SL(); //申请结点
|
||||
SPACE[i].data = A[j]; //录入A的元素值
|
||||
SPACE[r].cur = i; //插入到表尾
|
||||
r = i;
|
||||
}
|
||||
SPACE[r].cur =0; //尾结点指针为空
|
||||
|
||||
for(j=0; j<len_B; j++) //录入B的元素值
|
||||
{
|
||||
b = B[j];
|
||||
p = *S; //p指向集合A的头结点
|
||||
k = SPACE[*S].cur; //k指向集合A的第一个结点
|
||||
while(k && SPACE[k].data!=b)
|
||||
{ //在集合A中查找b
|
||||
p = k;
|
||||
k = SPACE[k].cur;
|
||||
}
|
||||
|
||||
if(!k) //A中找不到b,则将b插入A
|
||||
{ //新增元素将插入r结点的尾部
|
||||
i = Malloc_SL();
|
||||
SPACE[i].data = b;
|
||||
SPACE[i].cur = SPACE[r].cur;
|
||||
SPACE[r].cur = i; //r始终指向最后从A中插入的元素
|
||||
}
|
||||
else //A中存在b,则将b从A中删除
|
||||
{
|
||||
SPACE[p].cur = SPACE[k].cur;
|
||||
Free_SL(k);
|
||||
if(k==r)
|
||||
r = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
24
▲课本算法实现/▲02 线性表/07 Difference/Difference.h
Normal file
24
▲课本算法实现/▲02 线性表/07 Difference/Difference.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\07 Difference *
|
||||
* *
|
||||
* 文件名: Difference.h *
|
||||
* *
|
||||
* 内 容: 算法2.17相关操作列表 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#ifndef DIFFERENCE_H
|
||||
#define DIFFERENCE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
|
||||
#include "../06 StaticLinkedList/StaticLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 算法2.17函数列表 */
|
||||
void difference(SLinkList *S, LElemType_S A[], int len_A, LElemType_S B[], int len_B);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.17:在一维数组中建立集合(A-B)∪(B-A)┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
2
▲课本算法实现/▲02 线性表/07 Difference/TestData.txt
Normal file
2
▲课本算法实现/▲02 线性表/07 Difference/TestData.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
集合A:2 3 4
|
||||
集合B:1 3 4 6 7
|
||||
@@ -0,0 +1,146 @@
|
||||
/**********************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
|
||||
* *
|
||||
* 内 容: 双循环链表相关函数测试 *
|
||||
* *
|
||||
**********************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "DualCycleLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
Status CmpGreater(LElemType_DC e, LElemType_DC data); //若data>e,返回TRUE,否则返回FALSE
|
||||
void PrintElem(LElemType_DC e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DuLinkList L;
|
||||
int i;
|
||||
LElemType_DC e;
|
||||
|
||||
printf("▼1\n▲函数 InitList_DuL 测试...\n"); //1.函数InitList_DuL测试
|
||||
{
|
||||
printf("初始化双循环链表 L ...\n");
|
||||
InitList_DuL(&L);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼4\n▲函数 ListEmpty_DuL 测试...\n"); //4.函数ListEmpty_DuL测试
|
||||
{
|
||||
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼11\n▲函数 ListInsert_DuL 测试...\n"); //11.函数ListInsert_DuL测试
|
||||
{
|
||||
for(i=1; i<=6; i++)
|
||||
{
|
||||
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
|
||||
ListInsert_DuL(L, i, 2*i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼13\n▲函数 ListTraverse_DuL 测试...\n"); //13.函数ListTraverse_DuL测试
|
||||
{
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_DuL(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数 ListLength_DuL 测试...\n"); //5.函数ListLength_DuL测试
|
||||
{
|
||||
printf(" L 的长度为 %d \n", ListLength_DuL(L));
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼12\n▲函数 ListDelete_DuL 测试...\n"); //12.函数ListDelete_DuL测试
|
||||
{
|
||||
ListDelete_DuL(L, 6, &e);
|
||||
printf("删除 L 中第6个元素 \"%d\" ...\n", e);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_DuL(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数 GetElem_DuL 测试...\n"); //6.函数GetElem_DuL测试
|
||||
{
|
||||
GetElem_DuL(L, 4, &e);
|
||||
printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼7\n▲函数 LocateElem_DuL 测试...\n"); //7.函数LocateElem_DuL测试
|
||||
{
|
||||
i = LocateElem_DuL(L, 7, CmpGreater);
|
||||
printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数 PriorElem_DuL 测试...\n"); //8.函数PriorElem_DuL测试
|
||||
{
|
||||
PriorElem_DuL(L, 6, &e);
|
||||
printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼9\n▲函数 NextElem_DuL 测试...\n"); //9.函数NextElem_DuL测试
|
||||
{
|
||||
NextElem_DuL(L, 6, &e);
|
||||
printf("元素 \"6\" 的后继为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼10\n▲函数 GetElem_P 测试...\n"); //10.函数GetElem_P测试
|
||||
{
|
||||
DuLinkList p;
|
||||
p = GetElemPtr_DuL(L, 3);
|
||||
printf("链表第 3 个结点的指针为 0x%x,其对应的值为 \"%d\" \n", p, *p);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼3\n▲函数 ClearList_DuL 测试...\n"); //3.函数ClearList_DuL测试
|
||||
{
|
||||
printf("清空 L 前:");
|
||||
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
ClearList_DuL(L);
|
||||
printf("清空 L 后:");
|
||||
ListEmpty_DuL(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2\n▲函数 DestroyList_DuL 测试...\n"); //2.函数DestroyList_DuL测试
|
||||
{
|
||||
printf("销毁 L 前:");
|
||||
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
DestroyList_DuL(&L);
|
||||
printf("销毁 L 后:");
|
||||
L ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status CmpGreater(LElemType_DC e, LElemType_DC data)
|
||||
{
|
||||
return data>e ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_DC e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
258
▲课本算法实现/▲02 线性表/08 DualCycleLinkedList/DualCycleLinkedList.c
Normal file
258
▲课本算法实现/▲02 线性表/08 DualCycleLinkedList/DualCycleLinkedList.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/**********************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
|
||||
* *
|
||||
* 文件名: DualCycleLinkedList.c *
|
||||
* *
|
||||
* 算 法: 2.18、2.19 *
|
||||
* *
|
||||
**********************************************/
|
||||
|
||||
#ifndef DUALCYCLELINKEDLIST_C
|
||||
#define DUALCYCLELINKEDLIST_C
|
||||
|
||||
#include "DualCycleLinkedList.h" //**▲02 线性表**//
|
||||
|
||||
Status InitList_DuL(DuLinkList *L)
|
||||
{
|
||||
*L = (DuLinkList)malloc(sizeof(DuLNode));
|
||||
if(!(*L))
|
||||
exit(OVERFLOW);
|
||||
|
||||
(*L)->next = (*L)->prior = *L;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status ClearList_DuL(DuLinkList L)
|
||||
{
|
||||
DuLinkList p, q;
|
||||
|
||||
p = L->next;
|
||||
|
||||
while(p!=L)
|
||||
{
|
||||
q = p->next;
|
||||
free(p);
|
||||
p = q;
|
||||
}
|
||||
|
||||
L->next = L->prior = L;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void DestroyList_DuL(DuLinkList *L)
|
||||
{
|
||||
ClearList_DuL(*L);
|
||||
|
||||
free(*L);
|
||||
|
||||
*L = NULL;
|
||||
}
|
||||
|
||||
Status ListEmpty_DuL(DuLinkList L)
|
||||
{
|
||||
if(L && L->next==L && L->prior==L)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int ListLength_DuL(DuLinkList L)
|
||||
{
|
||||
DuLinkList p;
|
||||
int count;
|
||||
|
||||
if(L)
|
||||
{
|
||||
count = 0;
|
||||
p = L; //p指向头结点
|
||||
|
||||
while(p->next!=L) //p没到表头
|
||||
{
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
Status GetElem_DuL(DuLinkList L, int i, LElemType_DC *e)
|
||||
{
|
||||
DuLinkList p;
|
||||
int count;
|
||||
|
||||
if(L)
|
||||
{
|
||||
count = 1;
|
||||
p = L->next;
|
||||
|
||||
while(p!=L && count<i)
|
||||
{
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(p!=L)
|
||||
{
|
||||
*e = p->data;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int LocateElem_DuL(DuLinkList L, LElemType_DC e, Status(Compare)(LElemType_DC, LElemType_DC))
|
||||
{
|
||||
DuLinkList p;
|
||||
int count;
|
||||
|
||||
if(L)
|
||||
{
|
||||
count = 1;
|
||||
p = L->next;
|
||||
|
||||
while(p!=L && !Compare(e, p->data))
|
||||
{
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(p!=L)
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status PriorElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *pre_e)
|
||||
{
|
||||
DuLinkList p;
|
||||
|
||||
if(L)
|
||||
{
|
||||
p = L->next;
|
||||
|
||||
while(p!=L && p->data!=cur_e)
|
||||
p = p->next;
|
||||
|
||||
if(p!=L && p->prior!=L) //p不为首结点
|
||||
{
|
||||
*pre_e = p->prior->data;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Status NextElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *next_e)
|
||||
{
|
||||
DuLinkList p;
|
||||
|
||||
if(L)
|
||||
{
|
||||
p = L->next;
|
||||
|
||||
while(p!=L && p->data!=cur_e)
|
||||
p = p->next;
|
||||
|
||||
if(p!=L && p->next!=L)
|
||||
{
|
||||
*next_e = p->next->data;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
DuLinkList GetElemPtr_DuL(DuLinkList L, int i)
|
||||
{
|
||||
int count;
|
||||
DuLinkList p;
|
||||
|
||||
if(L && i>0)
|
||||
{
|
||||
count = 1;
|
||||
p = L->next;
|
||||
|
||||
while(p!=L && count<i)
|
||||
{
|
||||
count++;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if(p!=L)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.18 ║
|
||||
╚═════*/
|
||||
/* 与课本双链表插入算法略有不同,根源在于GetElemP_DuL不同 */
|
||||
Status ListInsert_DuL(DuLinkList L, int i, LElemType_DC e)
|
||||
{
|
||||
DuLinkList p, s;
|
||||
|
||||
if(i<1 || i>ListLength_DuL(L)+1) //先对i做出限制
|
||||
return ERROR;
|
||||
|
||||
p = GetElemPtr_DuL(L, i); //确定第i个结点指针
|
||||
if(!p) //此处若p=NULL,说明i = ListLength_DuL(L)+1
|
||||
p = L; //令p指向头指针
|
||||
|
||||
s = (DuLinkList)malloc(sizeof(DuLNode));
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
s->data = e;
|
||||
|
||||
s->prior = p->prior;
|
||||
p->prior->next = s;
|
||||
s->next = p;
|
||||
p->prior = s;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.19 ║
|
||||
╚═════*/
|
||||
Status ListDelete_DuL(DuLinkList L, int i, LElemType_DC *e)
|
||||
{
|
||||
DuLinkList p;
|
||||
|
||||
if(!(p=GetElemPtr_DuL(L, i))) //i值不合法
|
||||
return ERROR;
|
||||
|
||||
*e = p->data;
|
||||
p->prior->next = p->next;
|
||||
p->next->prior = p->prior;
|
||||
|
||||
free(p);
|
||||
p = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ListTraverse_DuL(DuLinkList L, void(Visit)(LElemType_DC))
|
||||
{
|
||||
DuLinkList p;
|
||||
|
||||
p = L->next; //p指向头结点,正向访问链表
|
||||
|
||||
while(p!=L)
|
||||
{
|
||||
Visit(p->data);
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
93
▲课本算法实现/▲02 线性表/08 DualCycleLinkedList/DualCycleLinkedList.h
Normal file
93
▲课本算法实现/▲02 线性表/08 DualCycleLinkedList/DualCycleLinkedList.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**********************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\08 DualCycleLinkedList *
|
||||
* *
|
||||
* 文件名: DualCycleLinkedList.h *
|
||||
* *
|
||||
* 内 容: 双向循环链表相关操作列表 *
|
||||
* *
|
||||
**********************************************/
|
||||
|
||||
#ifndef DUALCYCLELINKEDLIST_H
|
||||
#define DUALCYCLELINKEDLIST_H
|
||||
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 双循环链表类型定义 */
|
||||
typedef int LElemType_DC;
|
||||
typedef struct DuLNode
|
||||
{
|
||||
LElemType_DC data;
|
||||
struct DuLNode *prior;
|
||||
struct DuLNode *next;
|
||||
}DuLNode;
|
||||
typedef DuLNode* DuLinkList; //指向双循环链表结构的指针
|
||||
|
||||
/* 双循环链表函数列表 */
|
||||
Status InitList_DuL(DuLinkList *L);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(01)初始化双链表L。 ┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
Status ClearList_DuL(DuLinkList L);
|
||||
/*━━━━━━┓
|
||||
┃(02)置空L。 ┃
|
||||
┗━━━━━━*/
|
||||
|
||||
void DestroyList_DuL(DuLinkList *L);
|
||||
/*━━━━━━┓
|
||||
┃(03)销毁L。 ┃
|
||||
┗━━━━━━*/
|
||||
|
||||
Status ListEmpty_DuL(DuLinkList L);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(04)判断L是否为空。 ┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
int ListLength_DuL(DuLinkList L);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(05)返回L元素个数。 ┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
Status GetElem_DuL(DuLinkList L, int i, LElemType_DC *e);
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(06)用e接收L中第i个结点的元素值。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int LocateElem_DuL(DuLinkList L, LElemType_DC e, Status (Compare)(LElemType_DC, LElemType_DC));
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(07)返回L中第一个与e满足Compare关系的元素位序。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status PriorElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *pre_e);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(08)用pre_e接收cur_e的前驱。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
Status NextElem_DuL(DuLinkList L, LElemType_DC cur_e, LElemType_DC *next_e);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(09)用next_e接收cur_e的后继。 ┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
DuLinkList GetElemPtr_DuL(DuLinkList L, int i);
|
||||
/*━━━━━━━━━━━━━━━━┓
|
||||
┃(10)返回L中指向第i个结点的指针。┃
|
||||
┗━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListInsert_DuL(DuLinkList L, int i, LElemType_DC e);
|
||||
/*━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(11)算法2.18:在L第i个位置之前插入e。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListDelete_DuL(DuLinkList L, int i, LElemType_DC *e);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(12)算法2.19:删除L第i个位置的值,并用e接收。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void ListTraverse_DuL(DuLinkList L, void(Visit)(LElemType_DC));
|
||||
/*━━━━━━━━━━━┓
|
||||
┃(13)用Visit函数访问L。┃
|
||||
┗━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
265
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList-mian.c
Normal file
265
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList-mian.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 内 容: 扩展的单链表相关函数测试 *
|
||||
* *
|
||||
************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ExtenLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 函数原型 */
|
||||
Status CmpGreater(LElemType_E e, LElemType_E data); //判断data是否大于e //若data>e,返回TRUE
|
||||
void PrintElem(LElemType_E e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ELinkList L;
|
||||
Link p, q, s;
|
||||
PositionPtr r;
|
||||
int i;
|
||||
LElemType_E e;
|
||||
|
||||
printf("▼3\n▲函数 InitList_E 测试...\n"); //3.函数InitList_E测试
|
||||
{
|
||||
printf("初始化扩展的单链表 L ...\n");
|
||||
InitList_E(&L);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼14\n▲函数 ListEmpty_E 测试...\n"); //14.函数ListEmpty_E测试
|
||||
{
|
||||
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼23\n▲函数 ListInsert_L_E 测试...\n"); //23.函数ListInsert_L_E测试
|
||||
{
|
||||
for(i=1; i<=6; i++)
|
||||
{
|
||||
printf("在 L 第 %d 个位置插入 \"%d\" ...\n", i, 2*i);
|
||||
ListInsert_L_E(&L, i, 2*i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼22\n▲函数 ListTraverse_E 测试...\n"); //22.函数ListTraverse_E测试
|
||||
{
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼15\n▲函数 ListLength_E 测试...\n"); //15.函数ListLength_E测试
|
||||
{
|
||||
i = ListLength_E(L);
|
||||
printf(" L 的长度为 %d \n", i);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼24\n▲函数 ListDelete_E 测试...\n"); //24.函数ListDelete_L_E测试
|
||||
{
|
||||
ListDelete_L_E(&L, 6, &e);
|
||||
printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼20\n▲函数 LocatePos_E 测试...\n"); //20.函数LocatePos_E测试
|
||||
{
|
||||
LocatePos_E(L, 3, &p);
|
||||
printf(" L 中第 3 个元素 \"%d\" 的地址为 0x%x \n", p->data, p);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼18\n▲函数 PriorPos_E 测试...\n"); //18.函数PriorPos_E测试
|
||||
{
|
||||
r = PriorPos_E(L, p);
|
||||
printf("指针 p 指向的元素 \"%d\" 的前驱元素为 \"%d\" \n", p->data, r->data);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼19\n▲函数 NextPos_E 测试...\n"); //19.函数NextPos_E测试
|
||||
{
|
||||
r = NextPos_E(p);
|
||||
printf("指针 p 指向的元素 \"%d\" 的后继元素为 \"%d\" \n", p->data, r->data);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼21\n▲函数 LocateElem_E 测试...\n"); //21.函数LocateElem_E测试
|
||||
{
|
||||
r = LocateElem_E(L, 7, CmpGreater);
|
||||
printf(" L 中第一个元素值大于 7 的元素 \"%d\" 的地址为 0x%x \n", r->data, r);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼1\n▲函数 MakeNode_E 测试...\n"); //1.函数MakeNode_E测试
|
||||
{
|
||||
printf("创建结点 p ...\n");
|
||||
MakeNode_E(&p, 101);
|
||||
printf("创建结点 q ...\n");
|
||||
MakeNode_E(&q, 202);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼13\n▲函数 GetCurElem_E 测试...\n"); //13.函数GetCurElem_E测试
|
||||
{
|
||||
e = GetCurElem_E(p);
|
||||
printf("结点 p 的值为 \"%d\" \n", e);
|
||||
e = GetCurElem_E(q);
|
||||
printf("结点 q 的值为 \"%d\" \n", e);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼12\n▲函数 SetCurElem_E 测试...\n"); //12.函数SetCurElem_E测试
|
||||
{
|
||||
printf("用 888 替换 p 结点中的值...\n");
|
||||
SetCurElem_E(p, 888);
|
||||
printf("结点 p 的值为 \"%d\" \n", p->data);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2\n▲函数 FreeNode_E 测试...\n"); //2.函数FreeNode_E测试
|
||||
{
|
||||
printf("销毁结点 p 前:");
|
||||
p ? printf(" p 存在!\n") : printf(" p 不存在!!\n");
|
||||
FreeNode_E(&p);
|
||||
printf("销毁结点 p 后:");
|
||||
p ? printf(" p 存在!\n") : printf(" p 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数 Append_E 测试...\n"); //8.函数Append_E测试
|
||||
{
|
||||
printf("将 q 结点插在 L 最后一个结点之后...\n");
|
||||
Append_E(&L, q);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼9\n▲函数 Remove_E 测试...\n"); //9.函数Remove_E测试
|
||||
{
|
||||
printf("删除 L 中最后一个结点,用 p 接收删除的结点...\n");
|
||||
Remove_E(&L, &p);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数 InsFirst_E 测试...\n"); //6.函数InsFirst_E测试
|
||||
{
|
||||
printf("创建值为 303 的结点 p ...\n");
|
||||
MakeNode_E(&p, 303);
|
||||
printf("令 q 指向 L 中第 4 个元素...\n");
|
||||
LocatePos_E(L, 4, &q);
|
||||
printf("将 p 结点插入到以 q 作头结点的链表的第一个结点之前...\n");
|
||||
InsFirst_E(&L, q, p);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼7\n▲函数 DelFirst_E 测试...\n"); //7.函数DelFirst_E测试
|
||||
{
|
||||
printf("删除 L 中以第4个结点 q 为头结点的链表的第一个结点...\n");
|
||||
DelFirst_E(&L, q, &p);
|
||||
printf("当前 L 的值为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼16\n▲函数 GetHead_E 测试...\n"); //16.函数GetHead_E测试
|
||||
{
|
||||
p = GetHead_E(L);
|
||||
printf(" L 头指针为 p = L.head = 0x%x \n", p);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼17\n▲函数 GetLast_E 测试...\n"); //17.函数GetLast_E测试
|
||||
{
|
||||
q = GetLast_E(L);
|
||||
printf(" L 尾指针为 q = L.tail = 0x%x \n", q);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼10\n▲函数 InsBefore_E 测试...\n"); //10.函数InsBefore_E测试
|
||||
{
|
||||
printf("创建值为 404 的结点 s ...\n");
|
||||
MakeNode_E(&s, 404);
|
||||
printf("将结点 s 插入到尾结点 q 之前...\n");
|
||||
InsBefore(&L, &q, s);
|
||||
printf("当前 L 的值为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼11\n▲函数 InsAfter_E 测试...\n"); //11.函数InsAfter_E测试
|
||||
{
|
||||
printf("创建值为 505 的结点 s ...\n");
|
||||
MakeNode_E(&s, 505);
|
||||
printf("将结点 s 插入到头结点 p 之后...\n");
|
||||
InsAfter(&L, &p, s);
|
||||
printf(" L 中的元素为:L = ");
|
||||
ListTraverse_E(L, PrintElem);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼4\n▲函数 ClearList_E 测试...\n"); //4.函数ClearList_E测试
|
||||
{
|
||||
printf("清空 L 前:");
|
||||
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
ClearList_E(&L);
|
||||
printf("清空 L 后:");
|
||||
ListEmpty_E(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数 DestroyList_E 测试...\n"); //5.函数DestroyList_E测试
|
||||
{
|
||||
printf("销毁 L 前:");
|
||||
L.head!=NULL && L.tail!=NULL ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
DestroyList_E(&L);
|
||||
printf("销毁 L 后:");
|
||||
L.head!=NULL && L.tail!=NULL ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status CmpGreater(LElemType_E e, LElemType_E data)
|
||||
{
|
||||
return data>e ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_E e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
306
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList.c
Normal file
306
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList.c
Normal file
@@ -0,0 +1,306 @@
|
||||
/*****************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 文件名: ExtenLinkedList.c *
|
||||
* *
|
||||
* 算 法: 2.20 *
|
||||
* *
|
||||
*****************************/
|
||||
|
||||
#ifndef EXTENLINKEDLIST_C
|
||||
#define EXTENLINKEDLIST_C
|
||||
|
||||
#include "ExtenLinkedList.h" //**▲02 线性表**//
|
||||
|
||||
Status MakeNode_E(Link *p, LElemType_E e)
|
||||
{
|
||||
*p = (Link)malloc(sizeof(ELNode)); //申请空间
|
||||
if(!(*p))
|
||||
exit(OVERFLOW);
|
||||
|
||||
(*p)->data = e;
|
||||
(*p)->next = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void FreeNode_E(Link *p) //释放空间
|
||||
{
|
||||
free(*p);
|
||||
*p = NULL;
|
||||
}
|
||||
|
||||
Status InitList_E(ELinkList *L)
|
||||
{
|
||||
Link p;
|
||||
|
||||
p = (Link)malloc(sizeof(ELNode));
|
||||
if(!p)
|
||||
exit(OVERFLOW);
|
||||
p->next = NULL;
|
||||
|
||||
(*L).head = (*L).tail = p;
|
||||
(*L).len = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ClearList_E(ELinkList *L)
|
||||
{
|
||||
Link p, q;
|
||||
|
||||
p = (*L).head->next;
|
||||
|
||||
while(p)
|
||||
{
|
||||
q = p->next;
|
||||
free(p);
|
||||
p = q;
|
||||
}
|
||||
|
||||
(*L).head->next = NULL;
|
||||
(*L).tail = (*L).head;
|
||||
(*L).len = 0;
|
||||
}
|
||||
|
||||
void DestroyList_E(ELinkList *L)
|
||||
{
|
||||
ClearList_E(L);
|
||||
|
||||
free((*L).head);
|
||||
|
||||
(*L).head = (*L).tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
void InsFirst_E(ELinkList *L, Link h, Link s)
|
||||
{
|
||||
s->next = h->next;
|
||||
h->next = s;
|
||||
|
||||
if(h==(*L).tail) //若h为尾结点
|
||||
(*L).tail = h->next;
|
||||
|
||||
(*L).len++;
|
||||
}
|
||||
|
||||
Status DelFirst_E(ELinkList *L, Link h, Link *q)
|
||||
{
|
||||
*q = h->next;
|
||||
|
||||
if(*q) //链表非空
|
||||
{
|
||||
h->next = (*q)->next;
|
||||
if(!h->next) //h后只有一个结点
|
||||
(*L).tail = h;
|
||||
|
||||
(*L).len--; //并不释放被删结点所占空间
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
void Append_E(ELinkList *L, Link s)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
(*L).tail->next = s;
|
||||
|
||||
while(s) //考虑s为空的情况
|
||||
{
|
||||
(*L).tail = s;
|
||||
s = s->next;
|
||||
count++;
|
||||
}
|
||||
|
||||
(*L).len += count;
|
||||
}
|
||||
|
||||
Status Remove_E(ELinkList *L, Link *q)
|
||||
{
|
||||
Link p;
|
||||
|
||||
if(!(*L).len)
|
||||
{
|
||||
*q = NULL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
*q = (*L).tail;
|
||||
|
||||
p = (*L).head; //寻找尾结点的前驱
|
||||
while(p->next!=(*L).tail)
|
||||
p = p->next;
|
||||
p->next = NULL;
|
||||
(*L).tail = p;
|
||||
|
||||
(*L).len--;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void InsBefore(ELinkList *L, Link *p, Link s)
|
||||
{
|
||||
Link q;
|
||||
|
||||
q = PriorPos_E(*L, *p); //寻找p的前驱
|
||||
if(!q) //若p无前驱(只有一个结点)
|
||||
q = (*L).head;
|
||||
|
||||
s->next = *p;
|
||||
q->next = s;
|
||||
*p = s;
|
||||
|
||||
(*L).len++; //修改len,需用到*L
|
||||
}
|
||||
|
||||
void InsAfter(ELinkList *L, Link *p, Link s)
|
||||
{
|
||||
if(*p==(*L).tail)
|
||||
(*L).tail = s;
|
||||
|
||||
s->next = (*p)->next;
|
||||
(*p)->next = s;
|
||||
*p = s;
|
||||
|
||||
(*L).len++;
|
||||
}
|
||||
|
||||
void SetCurElem_E(Link p, LElemType_E e)
|
||||
{
|
||||
p->data = e;
|
||||
}
|
||||
|
||||
LElemType_E GetCurElem_E(Link p)
|
||||
{
|
||||
return p->data;
|
||||
}
|
||||
|
||||
Status ListEmpty_E(ELinkList L)
|
||||
{
|
||||
if(L.len)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int ListLength_E(ELinkList L)
|
||||
{
|
||||
return L.len;
|
||||
}
|
||||
|
||||
PositionPtr GetHead_E(ELinkList L)
|
||||
{
|
||||
return L.head;
|
||||
}
|
||||
|
||||
PositionPtr GetLast_E(ELinkList L)
|
||||
{
|
||||
return L.tail;
|
||||
}
|
||||
|
||||
PositionPtr PriorPos_E(ELinkList L, Link p)
|
||||
{
|
||||
Link q;
|
||||
|
||||
q = L.head->next;
|
||||
if(q==p) //首结点无前驱
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
while(q->next!=p) //寻找p的前驱
|
||||
q = q->next;
|
||||
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
PositionPtr NextPos_E(Link p)
|
||||
{
|
||||
return p->next;
|
||||
}
|
||||
|
||||
Status LocatePos_E(ELinkList L, int i, Link *p)
|
||||
{
|
||||
int count = 0;
|
||||
*p = L.head; //i=0时返回头指针
|
||||
|
||||
if(i<0 || i>L.len)
|
||||
return ERROR;
|
||||
|
||||
while(count<i)
|
||||
{
|
||||
count++;
|
||||
*p = (*p)->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
PositionPtr LocateElem_E(ELinkList L, LElemType_E e, Status(Compare)(LElemType_E,LElemType_E))
|
||||
{
|
||||
Link p = L.head->next;
|
||||
|
||||
while(p && !(Compare(e, p->data)))
|
||||
p = p->next;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
Status ListTraverse_E(ELinkList L, void(Visit)(LElemType_E))
|
||||
{
|
||||
Link p;
|
||||
int j;
|
||||
|
||||
p = L.head->next;
|
||||
|
||||
for(j=1; j<=L.len; j++)
|
||||
{
|
||||
Visit(p->data);
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.20 ║
|
||||
╚═════*/
|
||||
/* 算法2.9的改写 */
|
||||
Status ListInsert_L_E(ELinkList *L, int i, LElemType_E e)
|
||||
{
|
||||
Link h, s;
|
||||
|
||||
if(!LocatePos_E(*L, i-1, &h)) //定位第i-1个结点位置
|
||||
return ERROR; //i值不合法
|
||||
|
||||
if(!MakeNode_E(&s, e)) //创建结点
|
||||
return ERROR; //内存申请失败
|
||||
|
||||
InsFirst_E(L, h, s);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 算法2.10的改写,调用了本文档中定义的函数 */
|
||||
Status ListDelete_L_E(ELinkList *L, int i, LElemType_E *e)
|
||||
{
|
||||
Link p, q;
|
||||
|
||||
if(i<1 || i>(*L).len)
|
||||
return ERROR;
|
||||
|
||||
LocatePos_E(*L, i-1, &p);
|
||||
DelFirst_E(L, p, &q);
|
||||
|
||||
*e = q->data;
|
||||
free(q);
|
||||
q = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
156
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList.h
Normal file
156
▲课本算法实现/▲02 线性表/09 ExtenLinkedList/ExtenLinkedList.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表 *
|
||||
* *
|
||||
* 文件名: ExtenLinkedList.h *
|
||||
* *
|
||||
* 内 容: 扩展的单链表相关操作列表 *
|
||||
* *
|
||||
************************************/
|
||||
|
||||
#ifndef EXTENLINKEDLIST_H
|
||||
#define EXTENLINKEDLIST_H
|
||||
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
|
||||
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
|
||||
|
||||
/* 扩展的单链表类型定义 */
|
||||
#ifndef POLYNOMIAL_H //在多项式操作中,此类型需重新定义
|
||||
typedef int LElemType_E;
|
||||
#endif
|
||||
typedef struct ELNode //结点类型
|
||||
{
|
||||
LElemType_E data;
|
||||
struct ELNode *next;
|
||||
}ELNode;
|
||||
typedef ELNode* Link; //指向结构的指针
|
||||
typedef ELNode* PositionPtr;
|
||||
typedef struct //链表类型
|
||||
{
|
||||
Link head, tail; //分别指向线性链表中的头结点和尾结点
|
||||
int len; //指示线性链表中数据元素的个数
|
||||
}ELinkList;
|
||||
|
||||
/* 扩展的单链表函数列表 */
|
||||
Status MakeNode_E(Link *p, LElemType_E e);
|
||||
/*━━━━━━━━━━━━┓
|
||||
┃(01)分配由p指向e的结点。┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
void FreeNode_E(Link *p);
|
||||
/*━━━━━━━━━━━┓
|
||||
┃(02)释放p指向的结点。 ┃
|
||||
┗━━━━━━━━━━━*/
|
||||
|
||||
Status InitList_E(ELinkList *L);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(03)初始化一个空的线性链表。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
void ClearList_E(ELinkList *L);
|
||||
/*━━━━━━━━━━━━┓
|
||||
┃(04)重置线性链表L为空。 ┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
void DestroyList_E(ELinkList *L);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(05)销毁线性链表L。 ┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
void InsFirst_E(ELinkList *L, Link h, Link s);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(06)h指向L中的一个结点,将h当做头结点,将s插入到“第一个结点”之前。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status DelFirst_E(ELinkList *L, Link h, Link *q);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(07)h指向L中的一个结点,将h当做头结点,删除“第一个结点”,并用q接收。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void Append_E(ELinkList *L, Link s);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(08)将s所指的一串结点链接在L的最后一个结点之后,并改变L的尾指针。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status Remove_E(ELinkList *L, Link *q);
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(09)删除L的尾结点并用q接收,改变尾指针。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void InsBefore_E(ELinkList *L, Link *p, Link s);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(10)将s所指结点插入p所指结点之前,并将p指向新插入的结点。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void InsAfter_E(ELinkList *L, Link *p, Link s);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(11)将s所指结点插入p所指结点之后,并将p指向新插入的结点。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void SetCurElem_E(Link p, LElemType_E e);
|
||||
/*━━━━━━━━━━━━━━━┓
|
||||
┃(12)用e更新p指向的结点中的值。┃
|
||||
┗━━━━━━━━━━━━━━━*/
|
||||
|
||||
LElemType_E GetCurElem_E(Link p);
|
||||
/*━━━━━━━━━━━┓
|
||||
┃(13)返回p结点中的值。 ┃
|
||||
┗━━━━━━━━━━━*/
|
||||
|
||||
Status ListEmpty_E(ELinkList L);
|
||||
/*━━━━━┓
|
||||
┃(14)判空。┃
|
||||
┗━━━━━*/
|
||||
|
||||
int ListLength_E(ELinkList L);
|
||||
/*━━━━━┓
|
||||
┃(15)求长。┃
|
||||
┗━━━━━*/
|
||||
|
||||
PositionPtr GetHead_E(ELinkList L);
|
||||
/*━━━━━━━━━━━━━━━━━┓
|
||||
┃(16)以指针形式返回L头结点的位置。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
PositionPtr GetLast_E(ELinkList L);
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(17)以指针形式返回L最后一个结点的位置。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
PositionPtr PriorPos_E(ELinkList L, Link p);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(18)返回p指向的结点的前驱。 ┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
PositionPtr NextPos_E(Link p);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(19)返回p指向的结点的后继。 ┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
Status LocatePos_E(ELinkList L, int i, Link *p);
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(20)将*p指向L中第i个结点,i=0时为头结点。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
PositionPtr LocateElem_E(ELinkList L, LElemType_E e, Status(Compare)(LElemType_E,LElemType_E));
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(21)返回L中指向第一个与e满足Compare关系的元素指针。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListTraverse_E(ELinkList L, void(Visit)(LElemType_E));
|
||||
/*━━━━━┓
|
||||
┃(22)访问。┃
|
||||
┗━━━━━*/
|
||||
|
||||
Status ListInsert_L_E(ELinkList *L, int i, LElemType_E e);
|
||||
/*━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(23)算法2.20:在L第i个位置之前插入e。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status ListDelete_L_E(ELinkList *L, int i, LElemType_E *e);
|
||||
/*━━━━━━━━━━━━━━━━━━┓
|
||||
┃(24)删除L第i个位置的值,并用e接收。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
51
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList-main.c
Normal file
51
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList-main.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/****************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\10 MergeEList *
|
||||
* *
|
||||
* 内 容: 归并扩展的单链表相关函数测试 *
|
||||
* *
|
||||
****************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "MergeEList.c" //**▲02 线性表**//
|
||||
|
||||
void PrintElem(LElemType_E e); //测试函数,打印整型
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
ELinkList La, Lb, Lc;
|
||||
int m, n;
|
||||
|
||||
m = 6;
|
||||
n = 7;
|
||||
|
||||
printf("作为示例,La长度设定为 %d ,Lb设定为 %d ,创建La和Lb...\n", m, n);
|
||||
fp = fopen("TestData_La.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_ascend(fp, &La, m); //创建La与Lb
|
||||
fclose(fp);
|
||||
fp = fopen("TestData_Lb.txt", "r"); //文件指针,指向数据源
|
||||
CreateList_ascend(fp, &Lb, n);
|
||||
fclose(fp);
|
||||
|
||||
printf("La= "); //输出La与Lb
|
||||
ListTraverse_E(La, PrintElem);
|
||||
printf("\n");
|
||||
printf("Lb= ");
|
||||
ListTraverse_E(Lb, PrintElem);
|
||||
printf("\n\n");
|
||||
PressEnter;
|
||||
|
||||
MergeEList_L(La, Lb, &Lc, Cmp);
|
||||
printf("合并La和Lb为 Lc = ");
|
||||
ListTraverse_E(Lc, PrintElem);
|
||||
printf("\n\n");
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintElem(LElemType_E e)
|
||||
{
|
||||
printf("%d ", e);
|
||||
}
|
||||
83
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList.c
Normal file
83
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\10 MergeEList *
|
||||
* *
|
||||
* 文件名: MergeEList.c *
|
||||
* *
|
||||
* 算 法: 2.21 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#ifndef MERGEELIST_C
|
||||
#define MERGEELIST_C
|
||||
|
||||
#include "MergeEList.h" //**▲02 线性表**//
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.21 ║
|
||||
╚═════*/
|
||||
Status MergeEList_L(ELinkList La, ELinkList Lb, ELinkList *Lc, int(Compare)(LElemType_E c1, LElemType_E c2))
|
||||
{
|
||||
Link ha, hb, pa, pb, q;
|
||||
LElemType_E c1, c2;
|
||||
|
||||
if(!InitList_E(Lc)) //存储分配失败
|
||||
return ERROR;
|
||||
|
||||
ha = GetHead_E(La); //ha指向La头结点
|
||||
hb = GetHead_E(Lb); //hb指向Lb头结点
|
||||
pa = NextPos_E(ha); //pa指向La第一个结点
|
||||
pb = NextPos_E(hb); //pb指向Lb第一个结点
|
||||
while(!ListEmpty_E(La) && !ListEmpty_E(Lb))
|
||||
{ //La与Lb非空
|
||||
c1 = GetCurElem_E(pa); //c1、c2为当前比较的元素
|
||||
c2 = GetCurElem_E(pb);
|
||||
if(Compare(c1, c2)<=0)
|
||||
{
|
||||
DelFirst_E(&La, ha, &q);
|
||||
InsFirst_E(Lc, (*Lc).tail, q);
|
||||
pa = NextPos_E(ha);
|
||||
}
|
||||
else
|
||||
{
|
||||
DelFirst_E(&Lb, hb, &q);
|
||||
InsFirst_E(Lc, (*Lc).tail, q);
|
||||
pb=NextPos_E(hb);
|
||||
}
|
||||
}
|
||||
|
||||
if(!ListEmpty_E(La))
|
||||
Append_E(Lc, pa);
|
||||
else
|
||||
Append_E(Lc, pb);
|
||||
|
||||
FreeNode_E(&ha);
|
||||
FreeNode_E(&hb);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Cmp(LElemType_E c1, LElemType_E c2)
|
||||
{
|
||||
return c1-c2;
|
||||
}
|
||||
|
||||
Status CreateList_ascend(FILE *fp, ELinkList *L, int count)
|
||||
{ //按非降序序列创建链表L
|
||||
int i;
|
||||
LElemType_E e;
|
||||
|
||||
InitList_E(L);
|
||||
if(!L)
|
||||
return ERROR;
|
||||
|
||||
for(i=1; i<=count; i++)
|
||||
{
|
||||
Scanf(fp, "%d", &e);
|
||||
ListInsert_L_E(L, i, e);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
33
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList.h
Normal file
33
▲课本算法实现/▲02 线性表/10 MergeEList/MergeEList.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/****************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\10 MergeEList *
|
||||
* *
|
||||
* 文件名: MergeEList.h *
|
||||
* *
|
||||
* 内 容: 归并扩展的单链表相关操作列表 *
|
||||
* *
|
||||
****************************************/
|
||||
|
||||
#ifndef MERGEELIST_H
|
||||
#define MERGEELIST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../09 ExtenLinkedList/ExtenLinkedList.c" //**▲02 线性表**//
|
||||
|
||||
/* 归并扩展的单链表函数列表 */
|
||||
Status MergeEList_L(ELinkList La, ELinkList Lb, ELinkList *Lc, int(Compare)(LElemType_E c1, LElemType_E c2));
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.21:La与Lb均非递减排列,将其归并为一个非递减排列的单链表Lc。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int Cmp(LElemType_E c1, LElemType_E c2);
|
||||
/*━━━━━━━━━━━━━━━━┓
|
||||
┃(02)比较c1、c2大小,返回c1-c2。 ┃
|
||||
┗━━━━━━━━━━━━━━━━*/
|
||||
|
||||
Status CreateList_ascend(FILE *fp, ELinkList *L, int count);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(03)按非降序序列创建元素个数为count的扩展单链表L。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
1
▲课本算法实现/▲02 线性表/10 MergeEList/TestData_La.txt
Normal file
1
▲课本算法实现/▲02 线性表/10 MergeEList/TestData_La.txt
Normal file
@@ -0,0 +1 @@
|
||||
La = 1 2 3 5 7 8
|
||||
1
▲课本算法实现/▲02 线性表/10 MergeEList/TestData_Lb.txt
Normal file
1
▲课本算法实现/▲02 线性表/10 MergeEList/TestData_Lb.txt
Normal file
@@ -0,0 +1 @@
|
||||
Lb = 2 4 5 8 10 11 13
|
||||
106
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial-mian.c
Normal file
106
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial-mian.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\11 Polynomial *
|
||||
* *
|
||||
* 内 容: 一元多项式相关函数测试 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Polynomial.c" //**▲02 线性表**//
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
Polynomial Pa, Pb;
|
||||
int m, n, i;
|
||||
|
||||
m = 5;
|
||||
n = 6;
|
||||
|
||||
printf("▼1\n▲函数 CreatPolyn 测试...\n"); //1.函数CreatPolyn测试
|
||||
{
|
||||
printf("作为示范,创建项数为 %d 的多项式Pa...\n", m);
|
||||
fp = fopen("TestData_Pa.txt", "r"); //文件指针,指向数据源
|
||||
CreatPolyn_P(fp, &Pa, m);
|
||||
fclose(fp);
|
||||
printf("作为示范,创建项数为 %d 的多项式Pb...\n", n);
|
||||
fp = fopen("TestData_Pb.txt", "r");
|
||||
CreatPolyn_P(fp, &Pb, n);
|
||||
fclose(fp);
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼8\n▲函数 CreatPolyn 测试...\n"); //8.函数CreatPolyn测试
|
||||
{
|
||||
printf("一元多项式 Pa = ");
|
||||
PrintPolyn_P(Pa);
|
||||
printf("\n");
|
||||
printf("一元多项式 Pb = ");
|
||||
PrintPolyn_P(Pb);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼3\n▲函数 PolynLength_P 测试...\n"); //3.函数PolynLength_P测试
|
||||
{
|
||||
printf(" La 的项数为 %d ,Lb 的项数为 %d\n", PolynLength_P(Pa), PolynLength_P(Pb));
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼4、7\n▲函数 AddPolyn_P 等测试...\n"); //4、7.函数AddPolyn_P、Cmp_exp
|
||||
{
|
||||
AddPolyn_P(&Pa, &Pb);
|
||||
printf("Pa = Pa + Pb = ");
|
||||
PrintPolyn_P(Pa);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼2\n▲函数DestroyPolyn_P测试...\n"); //2.函数DestroyPolyn_P测试
|
||||
{
|
||||
printf("销毁 Pa 前:");
|
||||
(Pa.head && Pa.tail && Pa.len) ? printf(" Pa 存在!\n") : printf(" Pa 不存在!!\n");
|
||||
DestroyPolyn_P(&Pa);
|
||||
printf("销毁 Pa 后:");
|
||||
(Pa.head && Pa.tail && Pa.len) ? printf(" Pa 存在!\n") : printf(" Pa 不存在!!\n");
|
||||
printf("\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼5\n▲函数 SubtractPolyn_P 测试...\n"); //5.函数SubtractPolyn_P测试
|
||||
{
|
||||
fp = fopen("TestData_Pa.txt", "r");
|
||||
CreatPolyn_P(fp, &Pa, m);
|
||||
fclose(fp);
|
||||
fp = fopen("TestData_Pb.txt", "r");
|
||||
CreatPolyn_P(fp, &Pb, n);
|
||||
fclose(fp);
|
||||
SubtractPolyn_P(&Pa, &Pb);
|
||||
printf(" Pa = Pa - Pb = ");
|
||||
PrintPolyn_P(Pa);
|
||||
DestroyPolyn_P(&Pa);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
printf("▼6\n▲函数 MultiplyPolyn_P 测试...\n"); //6.函数MultiplyPolyn_P测试
|
||||
{
|
||||
fp = fopen("TestData_Pa.txt", "r");
|
||||
CreatPolyn_P(fp, &Pa, m);
|
||||
fclose(fp);
|
||||
fp = fopen("TestData_Pb.txt", "r");
|
||||
CreatPolyn_P(fp, &Pb, n);
|
||||
fclose(fp);
|
||||
MultiplyPolyn_P(&Pa, &Pb);
|
||||
printf(" Pa = Pa * Pb = ");
|
||||
PrintPolyn_P(Pa);
|
||||
DestroyPolyn_P(&Pa);
|
||||
printf("\n\n");
|
||||
}
|
||||
PressEnter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
275
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial.c
Normal file
275
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial.c
Normal file
@@ -0,0 +1,275 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\11 Polynomial *
|
||||
* *
|
||||
* 文件名: Polynomial.c *
|
||||
* *
|
||||
* 算 法: 2.22、2.23 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#ifndef POLYNOMIAL_C
|
||||
#define POLYNOMIAL_C
|
||||
|
||||
#include "Polynomial.h" //**▲02 线性表**//
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.22 ║
|
||||
╚═════*/
|
||||
void CreatPolyn_P(FILE *fp, Polynomial *P, int m)
|
||||
{
|
||||
PositionPtr h;
|
||||
ElemType_P e;
|
||||
int i;
|
||||
Link p;
|
||||
|
||||
InitList_E(P); //初始化一个扩展的单链表存放多项式
|
||||
h = GetHead_E(*P); //获取多项式头指针
|
||||
|
||||
e.coef = 0.0;
|
||||
e.expn = -1;
|
||||
SetCurElem_E(h, e); //设置头结点的数据元素
|
||||
h->next = NULL;
|
||||
|
||||
for(i=1; i<=m; i++) //依次录入n个非0项
|
||||
{
|
||||
Scanf(fp, "%f%d", &(e.coef), &(e.expn));
|
||||
MakeNode_E(&p, e);
|
||||
p->next = NULL;
|
||||
InsFirst_E(P, h, p);
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyPolyn_P(Polynomial *P)
|
||||
{
|
||||
DestroyList_E(P);
|
||||
}
|
||||
|
||||
int PolynLength_P(Polynomial P)
|
||||
{
|
||||
return ListLength_E(P);
|
||||
}
|
||||
|
||||
/*═════╗
|
||||
║ 算法2.23 ║
|
||||
╚═════*/
|
||||
void AddPolyn_P(Polynomial *Pa, Polynomial *Pb)
|
||||
{
|
||||
PositionPtr ha, hb;
|
||||
PositionPtr qa, qb;
|
||||
ElemType_P a, b;
|
||||
float sum;
|
||||
|
||||
ha = GetHead_E(*Pa); //ha、hb分别指向Pa、Pb头结点
|
||||
hb = GetHead_E(*Pb);
|
||||
qa = NextPos_E(ha); //qa、qb分别指向Pa、Pb的当前结点
|
||||
qb = NextPos_E(hb);
|
||||
|
||||
while(qa && qb) //qa、qb均非空
|
||||
{
|
||||
a = GetCurElem_E(qa); //a和b为两表中当前比较元素
|
||||
b = GetCurElem_E(qb);
|
||||
|
||||
switch(Cmp_exp(a,b)) //比较当前元素的指数大小
|
||||
{
|
||||
case -1: //多项式Pa中当前结点的指数值较小
|
||||
ha = qa;
|
||||
qa = NextPos_E(ha);
|
||||
break;
|
||||
case 0: //两者数值相等
|
||||
sum = a.coef + b.coef;
|
||||
if(sum != 0.0) //相加不能抵消时更新Pa结点的系数值
|
||||
{
|
||||
qa->data.coef = sum;
|
||||
SetCurElem_E(qa, qa->data);
|
||||
ha = qa; //此时ha需后移
|
||||
}
|
||||
else //相加抵消时,删除Pa中当前结点
|
||||
{
|
||||
DelFirst_E(Pa, ha, &qa);
|
||||
FreeNode_E(&qa);
|
||||
}
|
||||
DelFirst_E(Pb, hb, &qb); //删除Pb中扫描过的结点
|
||||
FreeNode_E(&qb);
|
||||
qb = NextPos_E(hb); //qa、qb均后移
|
||||
qa = NextPos_E(ha);
|
||||
break;
|
||||
case 1: //多项式Pb中当前结点的指数值较小
|
||||
DelFirst_E(Pb, hb, &qb); //摘下Pb当前结点
|
||||
InsFirst_E(Pa, ha, qb); //将摘下结点链入Pa中
|
||||
qb = NextPos_E(hb);
|
||||
ha = NextPos_E(ha);
|
||||
break;
|
||||
}//switch
|
||||
}//while
|
||||
|
||||
if(qb) //若Pb还未扫描完,将剩余项链接到Pa后
|
||||
Append_E(Pa, qb);
|
||||
|
||||
FreeNode_E(&hb); //释放Pb头结点
|
||||
(*Pb).head = (*Pb).tail = NULL; //设置Pb为销毁状态
|
||||
(*Pb).len = 0;
|
||||
}
|
||||
|
||||
void SubtractPolyn_P(Polynomial *Pa, Polynomial *Pb)
|
||||
{
|
||||
PositionPtr ha, hb;
|
||||
PositionPtr qa, qb;
|
||||
PositionPtr r;
|
||||
ElemType_P a, b;
|
||||
float sum;
|
||||
|
||||
ha = GetHead_E(*Pa); //ha、hb分别指向Pa、Pb头结点
|
||||
hb = GetHead_E(*Pb);
|
||||
qa = NextPos_E(ha); //qa、qb分别指向Pa、Pb的当前结点
|
||||
qb = NextPos_E(hb);
|
||||
|
||||
while(qa && qb) //qa、qb均非空
|
||||
{
|
||||
a = GetCurElem_E(qa); //a和b为两表中当前比较元素
|
||||
b = GetCurElem_E(qb);
|
||||
|
||||
switch(Cmp_exp(a,b)) //比较当前元素的指数大小
|
||||
{
|
||||
case -1: //多项式Pa中当前结点的指数值较小
|
||||
ha = qa;
|
||||
qa = NextPos_E(ha);
|
||||
break;
|
||||
case 0: //两者数值相等
|
||||
sum = a.coef - b.coef;
|
||||
if(sum != 0.0) //相减不能抵消时更新Pa结点的系数值
|
||||
{
|
||||
qa->data.coef = sum;
|
||||
SetCurElem_E(qa, qa->data);
|
||||
ha = qa; //此时ha需后移
|
||||
}
|
||||
else //相加抵消时,删除Pa中当前结点
|
||||
{
|
||||
DelFirst_E(Pa, ha, &qa);
|
||||
FreeNode_E(&qa);
|
||||
}
|
||||
DelFirst_E(Pb, hb, &qb); //删除Pb中扫描过的结点
|
||||
FreeNode_E(&qb);
|
||||
qb = NextPos_E(hb); //qa、qb均后移
|
||||
qa = NextPos_E(ha);
|
||||
break;
|
||||
case 1: //多项式Pb中当前结点的指数值较小
|
||||
DelFirst_E(Pb, hb, &qb); //摘下Pb当前结点
|
||||
qb->data.coef = - qb->data.coef; //改变当前结点符号
|
||||
InsFirst_E(Pa, ha, qb); //将摘下结点链入Pa中
|
||||
qb = NextPos_E(hb);
|
||||
ha = NextPos_E(ha);
|
||||
break;
|
||||
}//switch
|
||||
}//while
|
||||
|
||||
if(qb) //Pb还未扫描完
|
||||
{
|
||||
r = qb;
|
||||
while(r)
|
||||
{
|
||||
r->data.coef = - r->data.coef; //改变剩余结点符号
|
||||
r = r->next;
|
||||
}
|
||||
Append_E(Pa, qb);
|
||||
}
|
||||
|
||||
FreeNode_E(&hb); //释放Pb头结点
|
||||
(*Pb).head = (*Pb).tail = NULL;
|
||||
(*Pb).len = 0;
|
||||
}
|
||||
|
||||
void MultiplyPolyn_P(Polynomial *Pa, Polynomial *Pb)
|
||||
{
|
||||
Polynomial Pc, Ptmp;
|
||||
int i, j, la, lb;
|
||||
PositionPtr ha;
|
||||
PositionPtr qa, qb;
|
||||
Link s;
|
||||
|
||||
la = PolynLength_P(*Pa);
|
||||
lb = PolynLength_P(*Pb);
|
||||
ha = (*Pa).head;
|
||||
|
||||
InitList_E(&Pc);
|
||||
|
||||
for(i=1; i<=la; i++)
|
||||
{
|
||||
InitList_E(&Ptmp);
|
||||
|
||||
DelFirst_E(Pa, ha, &qa);
|
||||
qb = (*Pb).head->next;
|
||||
|
||||
for(j=1; j<=lb; j++)
|
||||
{
|
||||
s = (Link)malloc(sizeof(ELNode)); //申请空间
|
||||
if(!s)
|
||||
exit(OVERFLOW);
|
||||
|
||||
s->data.coef = qa->data.coef * qb->data.coef; //系数相乘
|
||||
s->data.expn = qa->data.expn + qb->data.expn; //指数相加
|
||||
s->next = NULL;
|
||||
|
||||
Append_E(&Ptmp, s);
|
||||
|
||||
qb = qb->next;
|
||||
}
|
||||
|
||||
AddPolyn_P(&Pc, &Ptmp);
|
||||
}
|
||||
|
||||
AddPolyn_P(Pa, &Pc);
|
||||
|
||||
DestroyPolyn_P(Pb);
|
||||
}
|
||||
|
||||
int Cmp_exp(ElemType_P c1, ElemType_P c2)
|
||||
{
|
||||
int i = c1.expn - c2.expn;
|
||||
|
||||
if(i<0)
|
||||
return -1;
|
||||
else if(i==0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PrintPolyn_P(Polynomial P)
|
||||
{
|
||||
int i;
|
||||
Link p;
|
||||
|
||||
p = P.head->next;
|
||||
for(i=1; i<=P.len; i++)
|
||||
{
|
||||
if(i==1)
|
||||
printf("%g", p->data.coef);
|
||||
else
|
||||
{
|
||||
if(p->data.coef>0)
|
||||
{
|
||||
printf(" + ");
|
||||
printf("%g", p->data.coef);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" - ");
|
||||
printf("%g", -p->data.coef);
|
||||
}
|
||||
}
|
||||
|
||||
if(p->data.expn)
|
||||
{
|
||||
printf("x");
|
||||
|
||||
if(p->data.expn!=1)
|
||||
printf("^%d", p->data.expn);
|
||||
}
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
68
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial.h
Normal file
68
▲课本算法实现/▲02 线性表/11 Polynomial/Polynomial.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*************************************
|
||||
* *
|
||||
* 文件夹: ▲02 线性表\11 Polynomial *
|
||||
* *
|
||||
* 文件名: Polynomial.h *
|
||||
* *
|
||||
* 内 容: 一元多项式相关操作列表 *
|
||||
* *
|
||||
*************************************/
|
||||
|
||||
#ifndef POLYNOMIAL_H
|
||||
#define POLYNOMIAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> //提供malloc、realloc、free、exit原型
|
||||
|
||||
/* 多项式类型定义 */
|
||||
typedef struct //用来表示多项式的项
|
||||
{
|
||||
float coef; //系数
|
||||
int expn; //指数
|
||||
}LElemType_E; //重新定义扩展的线性表中元素类型
|
||||
#include "../09 ExtenLinkedList/ExtenLinkedList.c"//**▲02 线性表**//
|
||||
typedef LElemType_E ElemType_P; //一元多项式项的类型
|
||||
typedef ELinkList Polynomial; //一元多项式
|
||||
|
||||
/* 一元多项式函数列表 */
|
||||
void CreatPolyn_P(FILE *fp, Polynomial *P, int m);
|
||||
/*━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(01)算法2.22:创建项数为m的一元多项式。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void DestroyPolyn_P(Polynomial *P);
|
||||
/*━━━━━━━━━━┓
|
||||
┃(02)销毁一元多项式。┃
|
||||
┗━━━━━━━━━━*/
|
||||
|
||||
int PolynLength_P(Polynomial P);
|
||||
/*━━━━━━━━━━━━━┓
|
||||
┃(03)返回一元多项式的项数。┃
|
||||
┗━━━━━━━━━━━━━*/
|
||||
|
||||
void AddPolyn_P(Polynomial *Pa, Polynomial *Pb);
|
||||
/*━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
┃(04)算法2.23:一元多项式加法Pa=Pa+Pb,销毁Pb。┃
|
||||
┗━━━━━━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void SubtractPolyn_P(Polynomial *Pa, Polynomial *Pb);
|
||||
/*━━━━━━━━━━━━━━━━━━┓
|
||||
┃(05)一元多项式减法Pa=Pa-Pb,销毁Pb。┃
|
||||
┗━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
void MultiplyPolyn_P(Polynomial *Pa, Polynomial *Pb);
|
||||
/*━━━━━━━━━━━━━━━━━━┓
|
||||
┃(06)一元多项式乘法Pa=Pa*Pb,销毁Pb。┃
|
||||
┗━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
int Cmp_exp(ElemType_P c1, ElemType_P c2);
|
||||
/*━━━━━━━━━━━━━━┓
|
||||
┃(07)比较c1项和c2项指数大小。┃
|
||||
┗━━━━━━━━━━━━━━*/
|
||||
|
||||
void PrintPolyn_P(Polynomial P);
|
||||
/*━━━━━━━━━━━━┓
|
||||
┃(08)打印输出一元多项式。┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
1
▲课本算法实现/▲02 线性表/11 Polynomial/TestData_Pa.txt
Normal file
1
▲课本算法实现/▲02 线性表/11 Polynomial/TestData_Pa.txt
Normal file
@@ -0,0 +1 @@
|
||||
Pa = (2.1 , 1) (4.0 , 3) (-3.12 , 5) (5.3 , 7) (2.5 , 9)
|
||||
1
▲课本算法实现/▲02 线性表/11 Polynomial/TestData_Pb.txt
Normal file
1
▲课本算法实现/▲02 线性表/11 Polynomial/TestData_Pb.txt
Normal file
@@ -0,0 +1 @@
|
||||
Pb = (3.4 , 2) (-3.17 , 4) (4.1 , 5) (1.8 , 8) (-2.5 , 9) (0.5 , 12)
|
||||
Reference in New Issue
Block a user