创建空链表 求长度 输出 后插法创建链表 查找第i个元素 插入 查找某个值的位置
删除 链表冒泡排序 两个无序链表 合并为一个有序链表
/*
创建空链表 求长度 输出 后插法创建链表 查找第i个元素 插入 查找某个值的位置
删除 链表冒泡排序 两个无序链表合并为一个有序链表
*/
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status; //Status是函数返回值类型,其值是函数结果状态代码
typedef int ElemType; //ElemType为可定义的数据类型,此设为int类型
typedef struct DLNode {
ElemType data;
struct DLNode *prior;
struct DLNode *next;
} DLNode, * DLinkList;
/**
* @brief 构造一个带头结点空双向链表
* @param DLinkList类型
* @retval 无
*/
Status DLinkList_Init(DLinkList &L) {
L = new DLNode;
L->prior = NULL;
L->next = NULL;
return OK;
}
/**
* @brief 求双向链表长度,头结点除外
* @param DLinkList类型
* @retval 长度int
*/
int DLinkList_Length(DLinkList L) {
int len = 0;
DLNode *p;
p = L;
if (!(p->next ))
return 0;
while (p = p->next )
++len;
return len;
}
/**
* @brief 顺序输出双链表
* @param DLinkList类型
* @retval 无
*/
void DLinkList_Output(DLinkList L) {
DLNode *p;
p = L;
while (p = p->next )
cout << p->data ;
cout << endl;
}
/**
* @brief 后插法,正序输入n个元素的值,建立带头结点的双向链表L
* @param DLinkList类型,元素个数n
* @retval 无
*/
void DLinkList_Create(DLinkList &L, int n) {
DLNode *p, *r;
L = new DLNode;
L->next = NULL;
r = L;
cout << "请输入" << n << "个数:\n";
for (int i = 0; i < n; i++) {
p = new DLNode;
cin >> p->data ;
p->next = NULL;
r->next = p;
p->prior = r;
r = p;
// p->prior = L->prior ;
// L->prior = p;
}
L->prior = NULL;
}
/* 书上是这样写的,我试了一下好像从后往前不太行
void DLinkList_Create(DLinkList &L, int n) {
DLNode *p, *r;
L = new DLNode;
L->next = NULL;
r = L;
cout << "请输入" << n << "个数:\n";
for (int i = 0; i < n; i++) {
p = new DLNode;
cin >> p->data ;
p->next = NULL;
r->next = p;
r = p;
p->prior = L->prior ;
L->prior = p;
}
}
*/
/**
* @brief 双向链表查找第i个元素的指针
* @param DLinkList类型,位置i
* @retval DLNode 类型
*/
DLNode *DLinkList_GetElem(DLinkList L, int i) {
int j;
DLNode *p;
p = L->next ;
j = 1;
while (j < i && p) {
p = p->next ;
++j;
}
if (!p || j > i)
return ERROR;
return p;
}
/**
* @brief 双向链表插入,i之前
* @param DLinkList类型,插入位置i,插入数据e
* @retval 无
*/
Status DLinkList_Insert(DLinkList &L, int i, ElemType e) {
DLNode *s, *p;
if (i > (DLinkList_Length(L) + 1))
return ERROR;
if (i == 1 && (!L->next )) {//第一个位置插入
p = new DLNode;
p->data = e;
L->next = p;
p->prior = L;
p->next = NULL;
return OK;
}
if (i == (DLinkList_Length(L) + 1)) {//最后一个位置插入
p = L;
for (int t = 0; t < (i - 1); ++t)
p = p->next ;
s = new DLNode;
s->data = e;
s->prior = p;
s->next = NULL;
p->next = s;
return OK;
}
p = L;
for (int t = 0; t < i; ++t)
p = p->next ;
s = new DLNode;
s->data = e;
s->prior = p->prior ;
p->prior ->next = s;
s->next = p;
p->prior = s;
return OK;
}
/**
* @brief 按值查找序号,当没有需要查找的值时,i=0
* @param LinkList类型,查找值,返回节点位置
* @retval 该值对应的节点
*/
DLNode *DLinkList_LocateElem(DLinkList L, ElemType e, int &i) {
i = 1;
DLNode *p;
p = L->next ;
while (p && p->data != e) {
++i;
p = p->next ;
}
if (!p)
i = 0;
return p;
}
/**
* @brief 双向链表删除第i个节点
* @param DLinkList类型,删除位置i
* @retval 删除数据e
*/
Status DLinkList_Delete(DLinkList &L, int i) {
int e;
DLNode *p;
if (!(p = DLinkList_GetElem(L, i)))
return ERROR;
e = p->data ;
p->prior ->next = p->next ;
p->next ->prior = p->prior ;
delete p;
return e;
}
/**
* @brief 数组冒泡排序,升序
* @param 数组类型,长度
* @retval 无
*/
void Array_Maopao(ElemType array[], int n) {
int i; //比较的轮数
int j; //每轮比较的次数
int buf; //交换数据时用于存放中间数据
for (i = 0; i < n - 1; ++i) { //比较n-1轮
for (j = 0; j < n - 1 - i; ++j) { //每轮比较n-1-i次,
if (array [j] > array [j + 1]) {
buf = array [j];
array [j] = array[j + 1];
array [j + 1] = buf;
}
}
}
}
/**
* @brief 双链表冒泡排序,升序
* @param DLinkList类型
* @retval 无
*/
void DLinkList_Maopao(DLinkList &a) {
int n, flag = 0;
DLNode *p;
p = a ;
n = DLinkList_Length(a);
ElemType array[n];
while (p = p->next ) {//把链表的值放到数组里,排序后再重新赋值
array[flag] = p->data ;
flag++;
}
Array_Maopao(array, n);
p = a ;
flag = 0;
while (p = p->next ) {
p->data = array[flag];
flag++;
}
free(array);
}
/**
* @brief 把无序双链表A和B合并到C中,不去重,升序
* @param DLinkList类型,DLinkList类型,DLinkList类型
* @retval 无
*/
void DLinkList_Union_Orderly(DLinkList A, DLinkList B, DLinkList &C) {
int n, flag = 0, flaga = 0, flagb = 0;
int a_len, b_len;
if (C->next ) {
cout << "目标链表非空,原链表为:" ;
DLinkList_Output(C);
}
ElemType temp;//临时存放当前节点数据
DLNode *pa, *pb, *pc;
pa = A ;
pb = B;
a_len = DLinkList_Length(A);
b_len = DLinkList_Length(B);
/***********************************************/
ElemType array_a[a_len];//把值放到数组里,进行排序,而不影响原链表顺序
ElemType array_b[b_len];
while (pa = pa->next ) {
array_a[flag] = pa->data ;
++flag;
}
Array_Maopao(array_a, flag );
flag = 0;
while (pb = pb->next ) {
array_b[flag] = pb->data ;
++flag;
}
Array_Maopao(array_b, flag );
/***********************************************/
flag = DLinkList_Length(C) + 1; //以下作链表C的插入位置
while (flaga < a_len && flagb < b_len) {
if (array_a[flaga] < array_b[flagb]) {
temp = array_a[flaga++];
DLinkList_Insert(C, flag++, temp);
} else {
temp = array_b[flagb++];
DLinkList_Insert(C, flag++, temp);
}
}
while (flaga < a_len) {
temp = array_a[flaga++];
DLinkList_Insert(C, flag++, temp);
}
while (flagb < b_len) {
temp = array_b[flagb++];
DLinkList_Insert(C, flag++, temp);
}
// free(array_a);//如果free的话会错误,不知道为啥
// free(array_b);
}
/****另一种写法,但还是不能释放数组的内存****/
//DLNode *DLinkList_Union_Orderly(DLinkList A, DLinkList B) {
// int n, flag = 0, flaga = 0, flagb = 0;
// int a_len, b_len;
// DLinkList C;
// DLinkList_Init(C);
// ElemType temp;//临时存放当前节点数据
// DLNode *pa, *pb, *pc;
// pa = A ;
// pb = B;
// a_len = DLinkList_Length(A);
// b_len = DLinkList_Length(B);
// /***********************************************/
// ElemType array_a[a_len];//把值放到数组里,进行排序,而不影响原链表顺序
// ElemType array_b[b_len];
// while (pa = pa->next ) {
// array_a[flag] = pa->data ;
// ++flag;
// }
// Array_Maopao(array_a, flag );
// flag = 0;
// while (pb = pb->next ) {
// array_b[flag] = pb->data ;
// ++flag;
// }
// Array_Maopao(array_b, flag );
// /***********************************************/
// flag = 1;//以下作链表C的插入位置
// while (flaga < a_len && flagb < b_len) {
// if (array_a[flaga] < array_b[flagb]) {
// temp = array_a[flaga++];
// DLinkList_Insert(C, flag++, temp);
// } else {
// temp = array_b[flagb++];
// DLinkList_Insert(C, flag++, temp);
// }
// }
// while (flaga < a_len) {
// temp = array_a[flaga++];
// DLinkList_Insert(C, flag++, temp);
// }
// while (flagb < b_len) {
// temp = array_b[flagb++];
// DLinkList_Insert(C, flag++, temp);
// }
// return C;
free(array_a);如果先free在return的话会错误,不知道为啥
free(array_b);
//}
+ 逆置
/**
* @brief 双链表的逆置
* @param DLinkList类型
* @retval 无
*/
Status DLinkList_Reverse(DLinkList &L) {
DLNode *p, *r, *q;
p = L;
if (!(p = p->next )) {
cout << "该链表为空" << endl;
return ERROR;
}
int len = DLinkList_Length(L);
while (--len) {
p = p->next ;
}
len = DLinkList_Length(L);
r = L;
r->next = NULL;
while (len--) {
q = p;
p = p->prior ;
q->next = r->next ;
q->prior = r;
r->next = q;
r = r->next ;
}
cout << "逆置后的链表为:";
DLinkList_Output(L);
return OK;
}