//
// main.cpp
// LinkList
//
// Created by T.P on 2019/1/31.
// Copyright © 2019 T.P. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>//malloc free
#define TRUE 1
#define FALSE 0
#define OK 0
#define ERROR -1
#define INFEASIBLE -1 //不可实行的
#define OVERFLOW -2 //溢出
typedef struct LNode{//LNode(结构名)
int data;
struct LNode *next=NULL;
}LNode,*LinkList;//LNode("struct LNode"的别名)
//线性链表L(未建立) | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//初始化 | 建立L的头结点[给L的头结点分配空间]
int InitList_L(LinkList &L){//此处修改了指针L,故需要用"引用"
L=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
L->data=0;
L->next=NULL;
if(!L)
exit(OVERFLOW);
return 0;
}
//线性链表L[已建立] | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//释放链表 | 释放L的头结点+后续节点
int FreeList_L(LinkList &L){//此处修改了指针L,故需要用"引用"
LinkList temporary=L;
while(temporary->next!=NULL){
temporary=L->next;
L->next=temporary->next;
free(temporary);
}
free(L);
return 0;
}
//打印线性链表元素
int Print_L(LinkList &L){//此处没有修改指针L,故可以不用"引用"
LinkList p=L;//p指向头结点(第零个结点)
while (p->next) {//打印y链表元素(不包括头结点)
printf("%d ",p->next->data);
p=p->next;
}
printf("
");
return 0;
}
//ALGORITHM_2_8
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//用e返回L中第i元素的值 | i从1计数
int GetElem_L(LinkList &L,int i,int &e){//此处没有修改指针L,故可以不用"引用"
LinkList p=L;//p指向头结点
int j=0;//第0结点
while (p&&j<i) {//找到第i结点(j=0头结点/j=1第1结点)
p=p->next;
++j;
}
if(!p||i<=0)//p为空/i输入错误 | 教材中(j>i)??
return ERROR;
e=p->data;
return OK;
}
//ALGORITHM_2_9
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//第i位置之前插入新的元素e | i从1计数
int InsertList_L(LinkList &L,int i,int e){//此处没有修改指针L,故可以不用"引用"
LinkList p=L;//p指向头结点(第零个结点)
int j=0;//第0结点
while (p&&j<i-1) {//找到第i-1结点(j=0头结点/j=1第1结点)
p=p->next;
++j;
}
if(!p||i<=0)//p为空/i输入错误 | ??教材中if(!p||j>i-1)
return ERROR;
LinkList s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return 0;
}
//ALGORITHM_2_10
//在线性链表L中 | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//删除第i元素并用e返回其值 | i从1计数
int DeleteList_L(LinkList &L,int i,int &e){//此处没有修改指针L,故可以不用"引用"
LinkList p=L;//p指向头结点(第零个结点)
int j=0;//第0结点
while (p&&j<i-1) {//找到第i-1结点(j=0头结点/j=1第1结点)
p=p->next;
++j;
}
if(!p||i<=0)//p为空/i输入错误 | ??教材中if(!p||j>i-1)
return ERROR;
LinkList s=p->next;
p->next=s->next;
e=s->data;
free(s);
return 0;
}
//ALGORITHM_2_11
//线性链表L(未建立) | L为带头结点的单链表的头指针[头结点(第0结点)]不存储数据
//逆位序输入n个元素的值
int CreateList_L(LinkList &L,int n){//此处修改了指针L,故需要用"引用"
L=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
L->data=0;
L->next=NULL;
for(int i=n;i>0;--i){
LinkList p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
return 0;
}
//ALGORITHM_2_12
//线性链表La,Lb元素按值非递减排列(递增)
//归并La,Lb得到新的单链表Lc,Lc的s值也按值非递减排列(递增)
int MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){//此处修改了指针L,故需要用"引用"
Lc=(LinkList)malloc(sizeof(LNode));//建立头结点,别忘记给头结点元素赋初值
Lc->data=0;
Lc->next=NULL;
LinkList La_p=La->next;//需要指向第一个节点
LinkList Lb_p=Lb->next;
LinkList Lc_p=Lc;
while(La_p!=NULL&&Lb_p!=NULL){//注意Lc的最后一个节点的next要置空
if(La_p->data<Lb_p->data){
Lc_p->next=La_p;
Lc_p=Lc_p->next;
La_p=La_p->next;
}
else{
Lc_p->next=Lb_p;
Lc_p=Lc_p->next;
Lb_p=Lb_p->next;
}
}
if(La_p!=NULL) //条件运算符 Lc_p->next=La_p?La_p:Lb_p
Lc_p->next=La_p;
else
Lc_p->next=Lb_p;
return 0;
}
int main(int argc, const char * argv[]) {
printf("OK
");
//LinkList a;//错误,该定义只是定义了一个指针并没有分配空间
//LNode a;//分配了空间
//注:因为是指针操作故函数传参不再需要"引用操作"
//也可如下操作:
//LinkList a;
//InitList_L(a);
LinkList a;
LinkList b;
LinkList c;
CreateList_L(a,4);
Print_L(a);
printf("OK
");
CreateList_L(b, 5);//需要输入
Print_L(b);
printf("OK
");
MergeList_L(a,b,c);
Print_L(c);
return 0;
}