这一章是有关双链表的算法分析和代码实现。 双链表的结点数据结构:
typedef struct DNode {
ElemType data;
struct DNode* prior;
struct DNode* next;
}DNode, *DLinkList;
主要有以下实现功能的函数:
-
DLinkList CreateListbyHeadInsert(DLinkList& L)) 功能:头插法建立双链表(逆向建立双链表); 参数:L:链表; 时间复杂度:O(n); -
DLinkList CreateListbyTailInsert(DLinkList& L) 功能:尾插法建立双链表(正向建立双链表); 参数:L:链表; 时间复杂度:O(n); -
DNode* GetNode(DLinkList& L, int i) 功能:按位查找,拿到第i个位置的结点并返回; 参数:L:链表 , i:要查找的结点的位置; 时间复杂度:O(n); -
DNode* LocateNode(DLinkList L, ElemType e) 功能:按值查找,查找第一个数据域和e相等第结点并返回; 参数:L:链表,e:要查找的结点的值; 时间复杂度:O(n); -
bool DNodeInsert(DLinkList& L, int i, ElemType e) 功能:插入结点,在第i个位置插入一个结点; 参数:L:链表 ,i:插入的位置,e:插入结点的值 时间复杂度:O(n); -
bool DNodeDelete(DLinkList& L, int i) 功能:删除结点,删除第i个结点; 参数:L:链表,i:删除结点的位置; 时间复杂度:O(n); -
bool DNodeRevise(DLinkList& L, int i, ElemType e) 功能:修改结点,将第i个结点的数据修改为e; 参数:L:链表,i:要修改的结点位置,e:要改成的值; 时间复杂度:O(n); -
int LinkLength(DLinkList L) 功能:求表长; 参数:L:链表; 时间复杂度:O(n); -
void PrintList(DLinkList L) 功能:输出所有结点的值; 参数:L:链表; 时间复杂度:O(n);
完整代码:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#define ElemType int
typedef struct DNode {
ElemType data;
struct DNode* prior;
struct DNode* next;
}DNode, *DLinkList;
void InitList(DLinkList& L) {
L = new DNode;
L->next = NULL;
L->prior = NULL;
}
DLinkList CreateListbyHeadInsert(DLinkList& L) {
InitList(L);
int x;
DNode* s;
DNode* p = L;
scanf("%d", &x);
while (x!=9999)
{
s = new DNode;
s->data = x;
s->next = p->next;
if(p->next)
p->next->prior = s;
s->prior = p;
p->next = s;
scanf("%d", &x);
}
return L;
}
DLinkList CreateListbyTailInsert(DLinkList& L) {
InitList(L);
int x;
DNode* s, * r = L;
scanf("%d", &x);
while (x != 9999)
{
s = new DNode;
s->data = x;
s->prior = r;
s->next = NULL;
r->next = s;
r = s;
scanf("%d", &x);
}
return L;
}
DNode* GetNode(DLinkList& L, int i) {
int j = 1;
DNode* p = L->next;
if (i == 0)
return L;
if (i < 1)
return NULL;
while (p && j < i)
{
p = p->next;
j++;
}
return p;
}
DNode* LocateNode(DLinkList L, ElemType e) {
DNode* p = L->next;
while (p != NULL && p->data != e)
{
p = p->next;
}
return p;
}
bool DNodeInsert(DLinkList& L, int i, ElemType e) {
DNode* s;
DLinkList p = L;
p = GetNode(L, i - 1);
if (!p)
return false;
s = new DNode;
s->data = e;
s->next = p->next;
if (p->next)
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
bool DNodeDelete(DLinkList& L, int i) {
DNode* q;
DLinkList p = L;
p = GetNode(L, i - 1);
if (!p)
return false;
q = p->next;
if (!q)
return false;
q = p->next;
p->next = q->next;
if(q->next)
q->next->prior = p;
free(q);
return true;
}
bool DNodeRevise(DLinkList& L, int i, ElemType e) {
DLinkList p = L;
p = GetNode(L, i);
if (!p || i == 0)
return false;
p->data = e;
return true;
}
int LinkLength(DLinkList L) {
DNode* p = L->next;
int sum = 0;
while (p)
{
p = p->next;
sum++;
}
return sum;
}
void PrintList(DLinkList L) {
DNode* p = L->next;
if (!p)
printf("表空\n");
else {
printf("双链表数据:\n");
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n共%d个元素\n", LinkLength(L));
}
}
void Insert(DLinkList& L) {
int location;
ElemType elem;
printf("输入要插入的元素:");
scanf("%d", &elem);
printf("要插入的位置:");
scanf("%d", &location);
if (DNodeInsert(L, location, elem))
printf("插入成功\n");
else
printf("插入失败\n");
}
void Delete(DLinkList& L) {
int location;
printf("输入要删除的元素的位置:");
scanf("%d", &location);
if (DNodeDelete(L, location))
printf("删除成功\n");
else
printf("删除失败\n");
}
void Revise(DLinkList& L) {
int i;
ElemType e;
printf("输入要修改的位置:");
scanf("%d", &i);
printf("修改为:");
scanf("%d", &e);
if (DNodeRevise(L, i, e))
printf("修改成功\n");
else
printf("修改失败\n");
}
void Search(DLinkList L) {
int searchChoice;
printf("(1)按位查找\n");
printf("(2)按值查找\n");
printf("选择查找功能:\n");
scanf("%d", &searchChoice);
int i;
ElemType e;
DNode* p;
switch (searchChoice)
{
case(1):
printf("输入要查找的节点位置:");
scanf("%d", &i);
p = GetNode(L, i);
if (p && i != 0)
printf("第%d个结点的值为%d\n", i, p->data);
else
printf("查找失败\n");
break;
case(2):
printf("输入要查找的结点的值:");
scanf("%d", &e);
p = LocateNode(L, e);
if (p)
printf("找到该元素,查找成功\n");
else
printf("找不到该元素,查找失败\n");
break;
default:
break;
}
}
void menu() {
printf("\n\n");
printf("①----------头插法建立双链表----------\n");
printf("②----------尾插法建立双链表----------\n");
printf("③---------- 打印表 ----------\n");
printf("④---------- 插入结点 ----------\n");
printf("⑤---------- 删除结点 ----------\n");
printf("⑥---------- 修改结点 ----------\n");
printf("⑦---------- 查找结点 ----------\n");
printf("\n\n");
}
int main() {
DLinkList L;
int choice;
do
{
menu();
scanf("%d", &choice);
switch (choice)
{
case(1):
printf("输入每个元素的值(输入9999停止建表)\n");
CreateListbyHeadInsert(L);
break;
case(2):
printf("输入每个元素的值(输入9999停止建表)\n");
CreateListbyTailInsert(L);
break;
case(3):
PrintList(L);
break;
case(4):
Insert(L);
break;
case(5):
Delete(L);
break;
case(6):
Revise(L);
break;
case(7):
Search(L);
break;
default:
break;
}
} while (choice != 0);
}
|