二.线性表的链表存储
一、设计需求描述
实现链表的建立、取元素、修改元素、插入、删除等链表的基本操作。
(1)依次从键盘读入数据,建立链表和链表;
(2)输出链表中的数据元素
(3)求链表的长度;
(4)根据指定条件能够取元素;
(5)实现在指定位置插入和删除元素的功能。
二、程序设计指导思想:
首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
三、程序算法设计
1、程序中的主要数据结构:
链表的插入查询、删除、显示、输出、退出。
2、程序算法的总体设计
主控菜单设计要求:程序运行后,给出5个菜单项的内容和输入提示:
1.链表的插入
2.链表的查询
3.链表的删除
4.链表的显示输出
5.退出
请选择1—5:
3、程序框图及必要的说明
对各个函数进行编写,设置主菜单用switch语句对其调用。
对各个变量信息宏定义,方便读懂。
程序具有一定的稳健性。
查询操作中指定查询第三个位置
删除操作指定删除第一个位置
采用尾插法和前插法两种方法进行插入操作,可以删除注释符号运行代码。
四、设计过程(界面)
五、设计总结
1、设计心得(150字左右)
在设计链表过程中,明白了算法的意义,对链表有了深刻的理解。
同时,在编写程序中,不满足于本题所给的几个操作,自己实现了合并,返回链表长度等其他操作算法及函数实现,在源代码中注释掉,只要删去注释符号即可使用。
感谢老师的认真指导及课堂的知识传授,只有上课认真听讲才能真正明白算法的精髓和难点所在,认真听讲才能学好数据结构。
2、存在问题及改进
一开始并不明白为什么要宏定义那么多变量,后来了解到是方便他人读程序,使自己的程序具有良好的维护性。
3、其它需说明的情况(如果有请说明)
源代码中注释掉的部分老师可不予考虑,这是我自己实现的其他函数功能,仅用于提高自己的编程水平和对算法的掌握程度。
六、程序代码
#include
#include
#define DECLARATION_H_INCLUDED
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define ElemType int
typedef ElemType* Triplet;
typedef int Status;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
void CreateList_L(LinkList *L, int n);
//前插尾插输入n个元素的值,建立带头结点的单链表L
Status ListInsert_L(LinkList *L , int i,ElemType e);
//在带头结点的单链线性表中第i个位置前插入元素e
Status ListDelete_L(LinkList *L, int i,ElemType e);
//在带头结点的单链线性表中,删除第i个元素并由e返回其值
Status GetElem_L(LinkList L, int i,ElemType *e);
//L为带头结点的单链表的头指针
//当第i个元素存在时将其值付给e并返回OK,否则返回ERROR
Status MergeList_L(LinkList *La, LinkList*Lb, LinkList *Lc);
//归并La和Lb表到Lc并按非递减序列排列
void PrintList_L(LinkList L);
//输出单链表中的内容
/*
void CreateList_L(LinkList *L, int n) //尾插法建立链表
{
Status i;
LinkList p;
*L=(LinkList)malloc (sizeof(LNode));
(*L)->next=NULL; //先建立带头结点的单链表;->的优先级比*高不要漏掉这里的括号
for(i=n; i>0 ;i--)
{ k
p=(LinkList)malloc((sizeof(LNode)));//生成新节点
scanf("%d",&p->data);
p->next=(*L)->next; //插入到表头
(* L)->next=p; // 数据是倒着插入链表的,即最后输入的数在表头
}
}//CreateList_L
*/
void CreateList_L(LinkList *L, int n) //前插法建立链表
{
Status i;
LinkList p,q;
*L=(LinkList)malloc (sizeof(LNode));
q=(*L);
(*L)->next=NULL; //先建立带头结点的单链表;->的优先级比*高不要漏掉这里的括号
for(i=0; i { p=(LinkList)malloc((sizeof(LNode)));//生成新节点 scanf("%d",&p->data); p->next=q->next; q->next=p; q=p; } }//CreateList_L Status ListInsert_L(LinkList *L , int i,ElemType e) { LinkList p=*L, s; ElemType j=0; while( p && j < i-1) { p=p->next; j++; } if(!p || j >i-1) returnERROR; //i小于1或大于表长加1 s=(LinkList)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; //先连接后插入 return OK; } Status ListDelete_L(LinkList *L, int i,ElemType *e) { LinkList p=*L, q; ElemType j=0; while(p->next && j < i-1) { p=p->next; j++; } if( !(p->next) || j > i-1) return ERROR;//删除位置不合理 q=p->next; p->next=q->next; *e=q->data; free(q); return *e; } Status GetElem_L(LinkList L, int i,ElemType *e) { LinkList p; ElemType j=1; p=L->next; while(p && j
{ p=p->next; j++; } if( !p || j>i) returnERROR; //第i个元素不存在 *e=p->data; return *e; }//GetElem_L() Status MergeList_L(LinkList *La, LinkList*Lb, LinkList *Lc) { //La和Lb两个链表中数据非递减排列 //归并La和Lb表到Lc并按非递减序列排列 LinkList pa, pb, pc; int i=0,j=0; pa=(*La)->next; pb=(*Lb)->next; printf("%x %x",(int)pa,(int )pb); (*Lc) =(LinkList)malloc(sizeof(LNode)); pc=(*Lc); while( (int)pa && (int)pb) { if( (pa->data) <=(pb->data)) { pc->next =pa; pc=pa; pa=pa->next; } else { pc->next=pb; pc=pb; pb=pb->next; } } while( pa ) { pc->next=pa;//插入剩余段 pc=pa; pa=pa->next; } while( pb) { pc->next=pb; pc=pb=NULL; } return OK; }//MergeList_L() void PrintList_L(LinkList L) { LinkList p; for(p=L->next;p;p=p->next)//L为链表的头结点数据域没有赋值 printf("%d ",p->data); printf("\n"); } void Welcome() { printf("\n\n"); printf("\t\t┏━━━━━━━━━━━━━━━┓\n"); printf("\t\t┃ 顺序表管理系统 ┃\n"); printf("\t\t┣━━━━━━━━━━━━━━━┫\n"); printf("\t\t┃ 1 插入 信 息 ┃\n"); printf("\t\t┃ 2 查询 信 息 ┃\n"); printf("\t\t┃ 3 删除 信 息 ┃\n"); printf("\t\t┃ 4 输出 信 息 ┃\n"); printf("\t\t┃ 5 退出 系 统 ┃\n"); printf("\t\t┗━━━━━━━━━━━━━━━┛\n"); printf("\t\t请选择:"); } int main() { Welcome(); ElemType e; LinkList *La; //LinkList *Lb, *Lc; La=(LinkList *)malloc(sizeof(LinkList)); /*Lb=(LinkList *)malloc(sizeof(LinkList)); Lc=(LinkList *)malloc(sizeof(LinkList));*/ intchoice; do{ printf("请输入选择序号:"); scanf("%d",&choice); switch(choice){ case1: printf("createla ,please enter 5 number:"); CreateList_L(La, 5); printf("插入成功!\n"); break; case2: printf("la表中第3个数是%d\n", GetElem_L(*La, 3, &e)); break; case3: printf("删除la表中的第一个数是%d\n", ListDelete_L(La, 1,&e)); printf("afterdelete first member ,la="); PrintList_L(*La); break; case4: printf("la="); PrintList_L(*La); break; case5: printf("已退出系统\n"); return 0; default: printf("您的输入有误!\n"); break; } }while(choice!=5); /* printf("create lb ,please enter 4 number:"); CreateList_L(Lb, 4); printf("lb="); PrintList_L(*Lb); ListInsert_L(Lb, 2, 3); printf("after insert 3, lb ="); PrintList_L(*Lb); printf("MergeList function ,Lc=\n"); if(MergeList_L(La, Lb, Lc) ==OK) { printf("mergetsuccess\n"); PrintList_L(*Lc); } else printf("mergetfailed"); */ return 0; }