单链表操作(附带菜单)
第二次复习数据结构了,实现这些功能还是比较容易的,功能也是比较完善的,可以复制下来编译运行。
#include<iostream>
#include <stdio.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int ElemType;//单链表结点date成员类型
typedef int Status;//函数返回值类型
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;//数据结构单链表定义
Status GetElem_L(LinkList L, int i, ElemType &e){
LinkList p = L->next;
int j = 1;
while(p && j<i){
p = p->next;
j++;
}
if(!p||j>i) return ERROR;
e = p->data;
return OK;
}//获取第i个结点
Status ListInsert_L(LinkList &L, int i, ElemType e){
LinkList p = L;
int j = 0;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p||j>i-1) return ERROR;
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}//插入结点到第i个位置
Status ListDelete_L(LinkList &L, int i){
LinkList p = L;
int j = 0;
while(p && j<i-1){
p = p->next;
j++;
}
if(!p || j>i-1) return ERROR;
LinkList q = p->next;
p->next = p->next->next;
return q->data;
free(q);
}//删除第i个结点
void ListUpdate_L(LinkList &L, int i, ElemType e){
LinkList p = L;
int j = 0;
while(p && j<i){
p = p->next;
j++;
}
if(!p || j>i) return;
p->data = e;
}//修改第i个结点
void ListReverse_L(LinkList &L){
LinkList p = L->next;
LinkList q =NULL;
while(p){
LinkList t = p;
p = p->next;
t->next = q;
q = t;
}
L->next = q;
}//翻转单链表
void CreateList_L(LinkList &L,int n){
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
for(int i=0;i<n;i++){
LinkList p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next = L->next;
L->next = p;
}
}//头插法创建单链表
void SortList_L(LinkList &L){
LinkList q = L->next;
if(!q) return;
while(q){
LinkList p = q->next;
while(p){
if(p->data < q->data){
int t = p->data;
p->data = q->data;
q->data = t;
}
p = p->next;
}
q = q->next;
}
}//链表排序
void MergeList_L(LinkList &A,LinkList &B,LinkList &C){
LinkList p = A->next;
LinkList q = B->next;
C = (LinkList)malloc(sizeof(LNode));
C->next = NULL;
LinkList r = C;
while(p && q){
LinkList s = (LinkList)malloc(sizeof(LNode));
if(q->data >= p->data){
s->data = p->data;
s->next = r->next;
r->next = s;
p = p->next;
}else{
s->data = q->data;
s->next = r->next;
r->next = s;
q = q->next;
}
r = r->next;
}
while(p){
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = p->data;
s->next = r->next;
r->next = s;
p = p->next;
r = r->next;
}
while(q){
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = q->data;
s->next = r->next;
r->next = s;
q = q->next;
r = r->next;
}
}//合并两个单链表并按降序排序
void PrintList_L(LinkList L){
LinkList p = L;
p = p->next;
while(p){
printf("%d->",p->data);
p = p->next;
}
printf("NULL\n");
}//打印单链表
typedef struct{
LinkList list[50];
ElemType length;
}Repository;//单链表仓库数据结构,顺序表
void AddLinkList(Repository &R,LinkList &L){
if(R.length<50){
R.list[R.length]=L;
R.length++;
}else {
printf("仓库已满!!!");
}
}//向仓库添加单链表
void PrintRepository(Repository R){
for(int i=0;i<R.length;i++){
printf("%d:",i+1);
PrintList_L(R.list[i]);
}
}//打印仓库中的单链表
void DeleteLinkList(Repository &R){
PrintRepository(R);
printf(" 请选择要删除的链表");
int j;
scanf("%d",&j);
if(R.length==0) return;
if(j<1||j>R.length) return;
for(int i = j;i<R.length;i++){
R.list[i-1] = R.list[i];
}
R.length--;
}//删除仓库中的单链表
LinkList GetLinkList(Repository &R,int i){
if(i<1||i>R.length) return NULL;
else return R.list[i-1];
}//获取单链表
void menu(Repository &R){
while(1){
system("cls");
LinkList l;
int i,n;
int w,e;
printf(" 单链表操作\n");
printf(" == == == == == == \n");
printf(" 1.创建单链表\n");
printf(" 2.查看单链表仓库\n");
printf(" 3.插入结点\n");
printf(" 4.删除结点\n");
printf(" 5.修改结点\n");
printf(" 6.查找结点\n");
printf(" 7.合并链表\n");
printf(" 8.删除链表\n");
printf(" 9.链表排序\n");
printf(" 10.翻转链表\n");
printf(" == == == == == == \n");
printf(" 请选择操作:");
scanf("%d",&i);
switch(i){
case 1:
printf(" 输入初始大小:");
scanf("%d",&n);
CreateList_L(l,n);
AddLinkList(R,l);
break;
case 2:
PrintRepository(R);
break;
case 3:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
printf(" 插入位置和元素值:");
scanf("%d%d",&w,&e);
l= GetLinkList(R,i);
ListInsert_L(l,w,e);
break;
case 4:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
printf(" 删除位置:");
scanf("%d",&w);
l= GetLinkList(R,i);
ListDelete_L(l,w);
break;
case 5:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
printf(" 修改位置和修改值:");
scanf("%d%d",&w,&e);
l= GetLinkList(R,i);
printf("修改前:");
PrintList_L(l);
ListUpdate_L(l,w,e);
printf("修改后:");
PrintList_L(l);
break;
case 6:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
printf(" 查找位置:");
scanf("%d",&w);
l = GetLinkList(R,i);
GetElem_L(l,w,e);
printf("第%d个结点是%d\n",w,e);
break;
case 7:
PrintRepository(R);
printf(" 选择两个链表:");
int j;
scanf("%d%d",&i,&j);
LinkList p,q;
l = GetLinkList(R,i);
p = GetLinkList(R,j);
MergeList_L(l,p,q);
AddLinkList(R,q);
break;
case 8:
DeleteLinkList(R);
break;
case 9:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
l = GetLinkList(R,i);
SortList_L(l);
break;
case 10:
PrintRepository(R);
printf(" 选择链表:");
scanf("%d",&i);
l = GetLinkList(R,i);
ListReverse_L(l);
break;
}
system("pause");
}
}//菜单函数
void main(){
Repository repository;
repository.length = 0;
menu(repository);
}