[数据结构]链表LinkList
- 1.3 链表
- 1.3.1 头插法建立单链表
- 1.3.2 限制链表长度建立单链表
- 1.3.3 尾插法建立单链表
- 1.3.4 按序号查找单链表
- 1.3.5 按值查找单链表
- 1.3.6 链表的插入
- 1.3.7 链表的删除
- 1.3.8 归并两个单链表
- 1.3.9 初始化单循环链表
- 1.3.10 查询元素的前驱和后继
- 1.3.11 单循环链表中元素的删除
- 1.3.12 单循环链表的清除和销毁
- 1.3.13 仅设表尾指针循环链表的合并
- 1.3.14 正序输出双向链表
- 1.3.15 逆向输出双向链表
- 1.3.16 删除双向链表中的节点
- 1.3.17 双向链表的元素个数
- 1.3.18 判断双向链表是否为空
- 1.3.19 双向链表元素值的查询
- 1.3.20 稀疏矩阵的建立
- 1.3.21 稀疏矩阵的删除
1.3 链表
1.3.1 头插法建立单链表
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node{
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void)
{
char ch;
linklist head;
listnode *p;
head=NULL;/*初始化为空*/
ch=getchar( );
while (ch!='\n'){
p=(listnode*)malloc(sizeof(listnode));/*分配空间*/
p->data=ch;/*数据域赋值*/
p->next=head;/*指定后继指针*/
head=p;/*head指针指定到新插入的结点上*/
ch=getchar( );
}
return (head);
}
int main()
{
linklist newlist=createlist();
do
{
printf("%c\n",newlist->data);
newlist=newlist->next;
}while(newlist!=NULL);
printf("\n");
return 0;
}
运行结果
1.3.2 限制链表长度建立单链表
#include <stdio.h>
#include <stdlib.h>
#define N 4
typedef char datatype;
typedef struct node{
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(int n)
{
int i;
linklist head;
listnode *p;
head=NULL;
for(i=n;i>0;--i)/*指定长度为n,插入次数受限制*/
{
p=(listnode*)malloc(sizeof(listnode));
scanf("%c",&p->data);
p->next=head;
head=p;
}
return(head);
}
int main()
{
linklist newlist=createlist(N);
do
{
printf("%c",newlist->data);
newlist=newlist->next;
}while(newlist!=NULL);
printf("\n");
return 0;
}
运行结果
1.3.3 尾插法建立单链表
#include <stdio.h>
#include <stdlib.h>
#define N 4
typedef char datatype;
typedef struct node{
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist creater()
{
char ch;
linklist head;
listnode *p,*r;
head=NULL;
r=NULL;/*r为尾指针*/
while((ch=getchar())!='\n'){
p=(listnode *)malloc(sizeof(listnode));
p->data=ch;
if(head==NULL)
head=p;/*head 指向第一个插入结点*/
else
r->next=p;/*插入到链表尾部*/
r=p;/*r指向最新结点,即最后结点*/
}
if (r!=NULL)
r->next=NULL;/*链表尾部结点的后继指针指定为空*/
return(head);
}
int main()
{
linklist newlist=creater();
do
{
printf("%c",newlist->data);
newlist=newlist->next;
}while(newlist!=NULL);
printf("\n");
return 0;
}
运行结果
1.3.4 按序号查找单链表
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node {
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void) {
char ch;
linklist head;
listnode *p;
head = NULL;/*初始化为空*/
ch = getchar();
while (ch != '\n') {
p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
p->data = ch;/*数据域赋值*/
p->next = head;/*指定后继指针*/
head = p;/*head指针指定到新插入的结点上*/
ch = getchar();
}
return (head);
}
listnode *getnode(linklist head, int i) {
int j;
listnode *p;
p = head;
j = 0;
while (p->next && j < i) {/*遍历第i个结点前的所有结点*/
p = p->next;
j++;
}
if (i == j) {
printf("%c\n", p->data);
return p;
} else
return NULL;
}
int main() {
linklist list;
listnode *node;
int i = 0;
list = createlist();
node = getnode(list, i);
return 0;
}
运行结果
1.3.5 按值查找单链表
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node {
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void) {
char ch;
linklist head;
listnode *p;
head = NULL;/*初始化为空*/
ch = getchar();
while (ch != '\n') {
p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
p->data = ch;/*数据域赋值*/
p->next = head;/*指定后继指针*/
head = p;/*head指针指定到新插入的结点上*/
ch = getchar();
}
return (head);
}
listnode *locatenode(linklist head, char key) {
listnode *p = head;
while (p->next && p->data != key)
p = p->next;
if (p != NULL)
printf("%c\n", p->data);
return p;
}
int main() {
linklist list;
listnode *node;
char key = 'c';
list = createlist();
node = locatenode(list, key);
return 0;
}
运行结果
1.3.6 链表的插入
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node {
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void) {
char ch;
linklist head;
listnode *p;
head = NULL;/*初始化为空*/
ch = getchar();
while (ch != '\n') {
p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
p->data = ch;/*数据域赋值*/
p->next = head;/*指定后继指针*/
head = p;/*head指针指定到新插入的结点上*/
ch = getchar();
}
return (head);
}
void insertnode(linklist head, char x, int i) {
int j = 0;
listnode *p, *s;
p = head;
while (p && j < i - 1) {
p = p->next;
++j;
}
if (!p || j > i - 1)
exit(1);
s = (linklist) malloc(sizeof(listnode));
s->data = x;
s->next = p->next;
p->next = s;
}
int main() {
linklist list;
int i = 1;
char x = 'c';
list = createlist();
insertnode(list, x, i);
do {
printf("%c", list->data);
list = list->next;
} while (list != NULL);
printf("\n");
return 0;
}
运行结果
1.3.7 链表的删除
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node{
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void)
{
char ch;
linklist head;
listnode *p;
head=NULL;/*初始化为空*/
ch=getchar( );
while (ch!='\n'){
p=(listnode*)malloc(sizeof(listnode));/*分配空间*/
p->data=ch;/*数据域赋值*/
p->next=head;/*指定后继指针*/
head=p;/*head指针指定到新插入的结点上*/
ch=getchar( );
}
return (head);
}
void deletelist(linklist head,int i)
{
int j=0;
listnode * p,*r;
p=head;
while(p&&j<i-1){
p=p->next;
++j;
}
if(!p->next||j>i-1)
exit(1);
r=p->next;
p->next=r->next;
free(r) ;
}
int main()
{
linklist list;
int i=1;
list=createlist();
deletelist(list,i);
do
{
printf("%c",list->data);
list=list->next;
}while(list!=NULL);
printf("\n");
return 0;
}
1.3.8 归并两个单链表
#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node {
datatype data;
struct node *next;
} listnode;
typedef listnode *linklist;
listnode *p;
linklist createlist(void) {
char ch;
linklist head;
listnode *p;
head = NULL;/*初始化为空*/
ch = getchar();
while (ch != '\n') {
p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
p->data = ch;/*数据域赋值*/
p->next = head;/*指定后继指针*/
head = p;/*head指针指定到新插入的结点上*/
ch = getchar();
}
return (head);
}
linklist concatenate(linklist list1, linklist list2) {
listnode *temp;
if (list1 == NULL)
return list2;
else {
if (list2 != NULL) {
for (temp = list1; temp->next; temp = temp->next); /*遍历到list1的末尾*/
temp->next = list2;/*将list2链接到list1末尾*/
}
}
return list1;
}
int main() {
linklist list1, list2, list3;
list1 = createlist();
list2 = createlist();
list3 = concatenate(list1, list2);
do {
printf("%c", list3->data);
list3 = list3->next;
} while (list3 != NULL);
printf("\n");
return 0;
}
1.3.9 初始化单循环链表
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h>
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
/* c2-2.h 线性表的单链表存储结构 */
struct LNode {
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
*L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if (!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next = *L; /* 指针域指向头结点 */
return OK;
}
Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L->next == L) /* 空 */
return TRUE;
else
return FALSE;
}
int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
LinkList p = L->next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i++;
p = p->next;
}
return i;
}
Status GetElem_CL(LinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j = 1; /* 初始化,j为计数器 */
LinkList p = L->next->next; /* p指向第一个结点 */
if (i <= 0 || i > ListLength_CL(L)) /* 第i个元素不存在 */
return ERROR;
while (j < i) { /* 顺指针向后查找,直到p指向第i个元素 */
p = p->next;
j++;
}
*e = p->data; /* 取第i个元素 */
return OK;
}
Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
LinkList p = (*L)->next, s; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
s->data = e; /* 插入L中 */
s->next = p->next;
p->next = s;
if (p == *L) /* 改变尾结点 */
*L = s;
return OK;
}
Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
LinkList p = L->next->next;
while (p != L->next) {
vi(p->data);
p = p->next;
}
printf("\n");
return OK;
}
void visit(ElemType c) {
printf("%d ", c);
}
int main() {
LinkList L;
ElemType e;
int j;
Status i;
i = InitList_CL(&L); /* 初始化单循环链表L */
printf("初始化单循环链表L i=%d (1:初始化成功)\n", i);
i = ListEmpty_CL(L);
printf("L是否空 i=%d(1:空 0:否)\n", i);
ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
ListInsert_CL(&L, 2, 5);
i = GetElem_CL(L, 1, &e);
j = ListLength_CL(L);
printf("L中数据元素个数=%d,第1个元素的值为%d。\n", j, e);
printf("L中的数据元素依次为:");
ListTraverse_CL(L, visit);
return 0;
}
运行结果
1.3.10 查询元素的前驱和后继
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h>
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
struct LNode {
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
*L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if (!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next = *L; /* 指针域指向头结点 */
return OK;
}
Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L->next == L) /* 空 */
return TRUE;
else
return FALSE;
}
int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
LinkList p = L->next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i++;
p = p->next;
}
return i;
}
Status GetElem_CL(LinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j = 1; /* 初始化,j为计数器 */
LinkList p = L->next->next; /* p指向第一个结点 */
if (i <= 0 || i > ListLength_CL(L)) /* 第i个元素不存在 */
return ERROR;
while (j < i) { /* 顺指针向后查找,直到p指向第i个元素 */
p = p->next;
j++;
}
*e = p->data; /* 取第i个元素 */
return OK;
}
Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
LinkList p = (*L)->next, s; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
s->data = e; /* 插入L中 */
s->next = p->next;
p->next = s;
if (p == *L) /* 改变尾结点 */
*L = s;
return OK;
}
Status PriorElem_CL(LinkList L, ElemType cur_e, ElemType *pre_e) { /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
/* 否则操作失败,pre_e无定义 */
LinkList q, p = L->next->next; /* p指向第一个结点 */
q = p->next;
while (q != L->next) /* p没到表尾 */
{
if (q->data == cur_e) {
*pre_e = p->data;
return TRUE;
}
p = q;
q = q->next;
}
return FALSE;
}
Status NextElem_CL(LinkList L, ElemType cur_e, ElemType *next_e) { /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
/* 否则操作失败,next_e无定义 */
LinkList p = L->next->next; /* p指向第一个结点 */
while (p != L) /* p没到表尾 */
{
if (p->data == cur_e) {
*next_e = p->next->data;
return TRUE;
}
p = p->next;
}
return FALSE;
}
void visit(ElemType c) {
printf("%d ", c);
}
int main() {
LinkList L;
ElemType e;
int j;
Status i;
i = InitList_CL(&L); /* 初始化单循环链表L */
printf("初始化单循环链表L i=%d (1:初始化成功)\n", i);
i = ListEmpty_CL(L);
printf("L是否空 i=%d(1:空 0:否)\n", i);
ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
ListInsert_CL(&L, 2, 5);
printf("依次插入元素3和5\n");
PriorElem_CL(L, 5, &e); /* 求元素5的前驱 */
printf("5前面的元素的值为%d。\n", e);
NextElem_CL(L, 3, &e); /* 求元素3的后继 */
printf("3后面的元素的值为%d。\n", e);
return 0;
}
运行结果
1.3.11 单循环链表中元素的删除
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#include<stdlib.h>
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int ElemType;
struct LNode {
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
*L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if (!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next = *L; /* 指针域指向头结点 */
return OK;
}
int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
LinkList p = L->next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i++;
p = p->next;
}
return i;
}
int LocateElem_CL(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)) { /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
/* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int i = 0;
LinkList p = L->next->next; /* p指向第一个结点 */
while (p != L->next) {
i++;
if (compare(p->data, e)) /* 满足关系 */
return i;
p = p->next;
}
return 0;
}
Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
LinkList p = (*L)->next, s; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
s->data = e; /* 插入L中 */
s->next = p->next;
p->next = s;
if (p == *L) /* 改变尾结点 */
*L = s;
return OK;
}
Status ListDelete_CL(LinkList *L, int i, ElemType *e) /* 改变L */
{ /* 删除L的第i个元素,并由e返回其值 */
LinkList p = (*L)->next, q; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L)) /* 第i个元素不存在 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
q = p->next; /* q指向待删除结点 */
p->next = q->next;
*e = q->data;
if (*L == q) /* 删除的是表尾元素 */
*L = p;
free(q); /* 释放待删除结点 */
return OK;
}
Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
LinkList p = L->next->next;
while (p != L->next) {
vi(p->data);
p = p->next;
}
printf("\n");
return OK;
}
Status compare(ElemType c1, ElemType c2) {
if (c1 == c2)
return TRUE;
else
return FALSE;
}
void visit(ElemType c) {
printf("%d ", c);
}
int main() {
LinkList L;
ElemType e;
int j;
Status i;
i = InitList_CL(&L); /* 初始化单循环链表L */
printf("依次在单循环链表中插入3,5\n");
ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
ListInsert_CL(&L, 2, 5);
j = LocateElem_CL(L, 5, compare);
if (j)
printf("L的第%d个元素为5。\n", j);
else
printf("不存在值为5的元素\n");
i = ListDelete_CL(&L, 2, &e);
printf("删除L的第2个元素:\n");
if (i) {
printf("删除的元素值为%d,现在L中的数据元素依次为:", e);
ListTraverse_CL(L, visit);
} else
printf("删除不成功!\n");
return 0;
}
运行结果
1.3.12 单循环链表的清除和销毁
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#include<stdlib.h>
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 1
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
struct LNode {
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
*L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if (!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next = *L; /* 指针域指向头结点 */
return OK;
}
Status DestroyList_CL(LinkList *L) { /* 操作结果:销毁线性表L */
LinkList q, p = (*L)->next; /* p指向头结点 */
while (p != *L) /* 没到表尾 */
{
q = p->next;
free(p);
p = q;
}
free(*L);
*L = NULL;
return OK;
}
Status ClearList_CL(LinkList *L) /* 改变L */
{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
LinkList p, q;
*L = (*L)->next; /* L指向头结点 */
p = (*L)->next; /* p指向第一个结点 */
while (p != *L) /* 没到表尾 */
{
q = p->next;
free(p);
p = q;
}
(*L)->next = *L; /* 头结点指针域指向自身 */
return OK;
}
Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L->next == L) /* 空 */
return TRUE;
else
return FALSE;
}
int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
LinkList p = L->next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i++;
p = p->next;
}
return i;
}
Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
LinkList p = (*L)->next, s; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
s->data = e; /* 插入L中 */
s->next = p->next;
p->next = s;
if (p == *L) /* 改变尾结点 */
*L = s;
return OK;
}
Status compare(ElemType c1, ElemType c2) {
if (c1 == c2)
return TRUE;
else
return FALSE;
}
void visit(ElemType c) {
printf("%d ", c);
}
int main() {
LinkList L;
ElemType e;
int j;
Status i;
i = InitList_CL(&L); /* 初始化单循环链表L */
printf("依次在单循环链表中插入3,5\n");
ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
ListInsert_CL(&L, 2, 5);
printf("清空L:%d(1: 成功)\n", ClearList_CL(&L));
printf("清空L后,L是否空:%d(1:空 0:否)\n", ListEmpty_CL(L));
printf("销毁L:%d(1: 成功)\n", DestroyList_CL(&L));
return 0;
}
运行结果
1.3.13 仅设表尾指针循环链表的合并
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#include <stdlib.h>
#define OVERFLOW 3
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
struct LNode {
ElemType data;
struct LNode *next;
};
typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
*L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
if (!*L) /* 存储分配失败 */
exit(OVERFLOW);
(*L)->next = *L; /* 指针域指向头结点 */
return OK;
}
int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
LinkList p = L->next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i++;
p = p->next;
}
return i;
}
Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
{ /* 在L的第i个位置之前插入元素e */
LinkList p = (*L)->next, s; /* p指向头结点 */
int j = 0;
if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1) /* 寻找第i-1个结点 */
{
p = p->next;
j++;
}
s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
s->data = e; /* 插入L中 */
s->next = p->next;
p->next = s;
if (p == *L) /* 改变尾结点 */
*L = s;
return OK;
}
Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
LinkList p = L->next->next;
while (p != L->next) {
vi(p->data);
p = p->next;
}
printf("\n");
return OK;
}
void MergeList_CL(LinkList *La, LinkList Lb) {
LinkList p = Lb->next;
Lb->next = (*La)->next;
(*La)->next = p->next;
free(p);
*La = Lb;
}
void visit(ElemType c) {
printf("%d ", c);
}
int main() {
int n = 5, i;
LinkList La, Lb;
InitList_CL(&La);
for (i = 1; i <= n; i++)
ListInsert_CL(&La, i, i);
printf("La="); /* 输出链表La的内容 */
ListTraverse_CL(La, visit);
InitList_CL(&Lb);
for (i = 1; i <= n; i++)
ListInsert_CL(&Lb, 1, i * 2);
printf("Lb="); /* 输出链表Lb的内容 */
ListTraverse_CL(Lb, visit);
MergeList_CL(&La, Lb);
printf("La+Lb="); /* 输出合并后的链表的内容 */
ListTraverse_CL(La, visit);
return 0;
}
1.3.14 正序输出双向链表
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
/* bo2-5.c 双链循环线性表(存储结构由c2-4.h定义)的基本操作(14个) */
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针*/
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
void ListTraverse(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit() */
DuLinkList p = L->next; /* p指向头结点 */
while (p != L) {
visit(p->data);
p = p->next;
}
printf("\n");
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i;
InitList(&L);
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
printf("正序输出链表:");
ListTraverse(L, vd); /* 正序输出 */
return 0;
}
1.3.15 逆向输出双向链表
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针*/
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,逆序对每个数据元素调用函数visit()。另加 */
DuLinkList p = L->prior; /* p指向尾结点 */
while (p != L) {
visit(p->data);
p = p->prior;
}
printf("\n");
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i;
InitList(&L);
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
printf("逆序输出链表:");
ListTraverseBack(L, vd); /* 逆序输出 */
}
运行结果
1.3.16 删除双向链表中的节点
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#include<stdlib.h>
#define OVERFLOW 3
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针*/
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
void ListTraverse(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit() */
DuLinkList p = L->next; /* p指向头结点 */
while (p != L) {
visit(p->data);
p = p->next;
}
printf("\n");
}
Status ListDelete(DuLinkList L, int i, ElemType *e) { /* 删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长+1 */
DuLinkList p;
if (i < 1 || i > ListLength(L)) /* i值不合法 */
return ERROR;
p = GetElemP(L, i); /* 在L中确定第i个元素的位置指针p */
if (!p) /* p=NULL,即第i个元素不存在 */
return ERROR;
*e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i, n = 2;
ElemType e;
InitList(&L);
printf("初始化链表依次输入1,2,3,4,5\n");
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
ListDelete(L, n, &e); /* 删除并释放第n个结点 */
printf("删除第%d个结点,值为%d,其余结点为:", n, e);
ListTraverse(L, vd); /* 正序输出 */
}
运行结果
1.3.17 双向链表的元素个数
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针(算法2.18、2.19要调用的函数) */
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) /* 改进算法2.18 */
{ /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i, n = 2;
ElemType e;
InitList(&L);
printf("初始化链表依次输入1,2,3,4,5\n");
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
printf("链表的元素个数为%d\n", ListLength(L));
return 0;
}
运行结果
1.3.18 判断双向链表是否为空
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
Status ClearList(DuLinkList L) /* 不改变L */
{ /* 初始条件:L已存在。操作结果:将L重置为空表 */
DuLinkList q, p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
q = p->next;
free(p);
p = q;
}
L->next = L->prior = L; /* 头结点的两个指针域均指向自身 */
return OK;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针(算法2.18、2.19要调用的函数) */
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) /* 改进算法2.18 */
{ /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
Status ListEmpty(DuLinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L->next == L && L->prior == L)
return TRUE;
else
return FALSE;
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i, n = 2;
ElemType e;
InitList(&L);
printf("初始化链表依次输入1,2,3,4,5\n");
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
printf("链表是否空:%d(1:是 0:否)\n", ListEmpty(L));
ClearList(L); /* 清空链表 */
printf("清空后,链表是否空:%d(1:是 0:否)\n", ListEmpty(L));
return 0;
}
运行结果
1.3.19 双向链表元素值的查询
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<math.h> /* floor(),ceil(),abs() */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW 3
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;
typedef struct DuLNode {
ElemType data;
struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
*L = (DuLinkList) malloc(sizeof(DuLNode));
if (*L) {
(*L)->next = (*L)->prior = *L;
return OK;
} else
return OVERFLOW;
}
Status ClearList(DuLinkList L) /* 不改变L */
{ /* 初始条件:L已存在。操作结果:将L重置为空表 */
DuLinkList q, p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
q = p->next;
free(p);
p = q;
}
L->next = L->prior = L; /* 头结点的两个指针域均指向自身 */
return OK;
}
int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0;
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L) /* p没到表头 */
{
i++;
p = p->next;
}
return i;
}
Status GetElem(DuLinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j = 1; /* j为计数器 */
DuLinkList p = L->next; /* p指向第一个结点 */
while (p != L && j < i) /* 顺指针向后查找,直到p指向第i个元素或p指向头结点 */
{
p = p->next;
j++;
}
if (p == L || j > i) /* 第i个元素不存在 */
return ERROR;
*e = p->data; /* 取第i个元素 */
return OK;
}
DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
{ /* 在双向链表L中返回第i个元素的位置指针*/
int j;
DuLinkList p = L;
for (j = 1; j <= i; j++)
p = p->next;
return p;
}
Status ListInsert(DuLinkList L, int i, ElemType e) {
DuLinkList p, s;
if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
return ERROR;
p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
if (!p) /* p=NULL,即第i-1个元素不存在 */
return ERROR;
s = (DuLinkList) malloc(sizeof(DuLNode));
if (!s)
return OVERFLOW;
s->data = e; /* 在第i-1个元素之后插入 */
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
Status ListEmpty(DuLinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L->next == L && L->prior == L)
return TRUE;
else
return FALSE;
}
void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
{
printf("%d ", c);
}
int main() {
DuLinkList L;
int i, n, j;
ElemType e;
InitList(&L);
printf("初始化链表依次输入1,2,3,4,5\n");
for (i = 1; i <= 5; i++)
ListInsert(L, i, i); /* 在第i个结点之前插入i */
n = 3;
j = GetElem(L, n, &e); /* 将链表的第n个元素赋值给e */
if (j)
printf("链表的第%d个元素值为%d\n", n, e);
else
printf("不存在第%d个元素\n", n);
}
运行结果
1.3.20 稀疏矩阵的建立
#include "stdio.h"
#include "stdlib.h"
#define MAX_SIZE 50 /* 最大的稀疏矩阵 */
typedef enum {head, entry} tagfield;
struct entry_node {
int row;
int col;
int value;
};
typedef struct Matrix {
struct Matrix * down;
struct Matrix * right;
tagfield tag;
union {
struct Matrix * next;
struct entry_node entry;
} u;
}matrix_node;
typedef matrix_node * matrix_pointer;
matrix_pointer hdnode [ MAX_SIZE ];
matrix_pointer new_node(void)
{
matrix_pointer temp;
temp = (matrix_pointer)malloc(sizeof(matrix_node));
if (temp==NULL) {
printf("The memory is full\n");
exit(1);
}
return temp;
}
matrix_pointer Create(void)
{
int num_rows, num_cols, num_terms, num_heads, i,current_row;
int col, value,row;
matrix_pointer node,temp,last;
printf("Enter the number of rows, columns and number of nonzero terms: ");
scanf("%d%d%d",&num_rows,&num_cols,&num_terms);
num_heads = (num_cols > num_rows) ? num_cols :num_rows;
/* 建立新结点 */
node = new_node();
node->tag = entry;
node->u.entry.row = num_rows;
node->u.entry.col = num_cols;
if ( !num_heads )
node->right = node;
else {
for ( i = 0; i<num_heads; i++ ) {
temp = new_node();
hdnode[i] = temp;
hdnode[i]->tag = head;
hdnode[i]->right = temp;
hdnode[i]->u.next = temp;
}
current_row = 0;
last = hdnode[0];
for ( i = 0; i < num_terms; i++ ) {
printf("Enter row, column and value: ");
scanf("%d%d%d",&row,&col,&value);
if ( row > current_row ) {
/* 转到row所在行去*/
last->right = hdnode[current_row];
current_row = row;
last = hdnode[row];
}
temp = new_node();
temp->tag = entry;
temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
last->right = temp;
last = temp;
/*链接到列结点上 */
hdnode[col]->u.next->down = temp;
hdnode[col]->u.next = temp;
}
/* 结束上一行结点 */
last->right = hdnode[current_row];
/*结束所有行结点*/
for ( i=0; i<num_cols; i++ )
hdnode[i]->u.next->down= hdnode[i];
/*链接所有的头结点 */
for ( i=0; i<num_heads-1; i++ )
hdnode[i]->u.next = hdnode[i+1];
hdnode[num_heads-1]->u.next = node;
node->right = hdnode[0];
}
return node;
}
int main()
{
matrix_pointer matric=Create();
return 0;
}
运行结果
1.3.21 稀疏矩阵的删除
#include <cstdlib>
#include "stdio.h"
#define MAX_SIZE 50 /* 最大的稀疏矩阵 */
typedef enum {
head, entry
} tagfield;
struct entry_node {
int row;
int col;
int value;
};
typedef struct Matrix {
struct Matrix *down;
struct Matrix *right;
tagfield tag;
union {
struct Matrix *next;
struct entry_node entry;
} u;
} matrix_node;
typedef matrix_node *matrix_pointer;
matrix_pointer hdnode[MAX_SIZE];
matrix_pointer new_node(void) {
matrix_pointer temp;
temp = (matrix_pointer) malloc(sizeof(matrix_node));
if (temp == NULL) {
printf("The memory is full\n");
exit(1);
}
return temp;
}
matrix_pointer Create(void) {
int num_rows, num_cols, num_terms, num_heads, i, current_row;
int col, value, row;
matrix_pointer node, temp, last;
printf("Enter the number of rows, columns and number of nonzero terms: ");
scanf("%d%d%d", &num_rows, &num_cols, &num_terms);
num_heads = (num_cols > num_rows) ? num_cols : num_rows;
/* 建立新结点 */
node = new_node();
node->tag = entry;
node->u.entry.row = num_rows;
node->u.entry.col = num_cols;
if (!num_heads)
node->right = node;
else { /*初始化头结点如图5-5-4*/
for (i = 0; i < num_heads; i++) {
temp = new_node();
hdnode[i] = temp;
hdnode[i]->tag = head;
hdnode[i]->right = temp;
hdnode[i]->u.next = temp;
}
current_row = 0;
last = hdnode[0];
for (i = 0; i < num_terms; i++) {
printf("Enter row, column and value: ");
scanf("%d%d%d", &row, &col, &value);
if (row > current_row) {
/* 转到row所在行去*/
last->right = hdnode[current_row];
current_row = row;
last = hdnode[row];
}
temp = new_node();
temp->tag = entry;
temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
/* 链接到行结点上如图5-5-5所示 */
last->right = temp;
last = temp;
/*链接到列结点上 */
hdnode[col]->u.next->down = temp;
hdnode[col]->u.next = temp;
}
/* 结束上一行结点 */
last->right = hdnode[current_row];
/*结束所有行结点*/
for (i = 0; i < num_cols; i++)
hdnode[i]->u.next->down = hdnode[i];
/*链接所有的头结点 */
for (i = 0; i < num_heads - 1; i++)
hdnode[i]->u.next = hdnode[i + 1];
hdnode[num_heads - 1]->u.next = node;
node->right = hdnode[0];
}
return node;
}
void erase(matrix_pointer *node) {
matrix_pointer x, y, head = (*node)->right;
int i;
/* 遍历每行,删除元素结点和头结点 */
for (i = 0; i < (*node)->u.entry.row; i++) {
y = head->right;
while (y != head) {
x = y;
y = y->right;
free(x);
}
x = head;
head = head->u.next;
free(x);
}
/* 删除剩余的头结点*/
y = head;
while (y != *node) {
x = y;
y = y->u.next;
free(x);
}
free(*node);
*node = NULL;
}
int main() {
matrix_pointer matric = Create();
erase(&matric);
return 0;
}
[数据结构]链表LinkList的更多相关文章
- [数据结构]链表相关的实现LinkList.cpp
目录 LinkList.cpp //链表相关操作的实现 LinkList.h LinkListManager.cpp //链表相关实现函数的调用 LinkListManager.h LinkList. ...
- [PHP] 数据结构-链表创建-插入-删除-查找的PHP实现
链表获取元素1.声明结点p指向链表第一个结点,j初始化1开始2.j<i,p指向下一结点,因为此时p是指向的p的next,因此不需要等于3.如果到末尾了,p还为null,就是没有查找到 插入元素1 ...
- Python—数据结构——链表
数据结构——链表 一.简介 链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构.由一系列节点组成的元素集合.每个节点包含两部分,数据域item和指向下一个节 ...
- (js描述的)数据结构[链表](4)
(js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...
- 数据结构和算法(Golang实现)(12)常见数据结构-链表
链表 讲数据结构就离不开讲链表.因为数据结构是用来组织数据的,如何将一个数据关联到另外一个数据呢?链表可以将数据和数据之间关联起来,从一个数据指向另外一个数据. 一.链表 定义: 链表由一个个数据节点 ...
- Redis数据结构—链表与字典的结构
目录 Redis数据结构-链表与字典的结构 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 Redis字典的使用 Re ...
- Redis数据结构—链表与字典
目录 Redis数据结构-链表与字典 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 哈希算法 解决键冲突 rehas ...
- Java数据结构与算法(5) - ch05链表(LinkList)
双端链表与传统链表非常相似,但是它有一个新增的特性:即对最后一个链节点的引用,就像对第一个连接点的引用一样.注意与双向链表进行区别.
- Python 数据结构 链表
什么是时间复杂度 时间频度:一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才知道.但是我们不可能也没有必要对每一个算法都进行上机测试,只需要知道那个算法花费的时间多,那个算法花费得 ...
随机推荐
- day11 系统安全
day11 系统安全 复习总结 文件 1.创建 格式:touch [路径] [root@localhost ~]# touch 1.txt # 当前路径创建 [root@localhost ~]# t ...
- Vue面试专题(未完)
1.谈一下你对MVVM原理的理解 传统的 MVC 指的是,用户操作会请求服务端路由,路由会调用对应的控制器来处理,控制器会获取数 据.将结果返回给前端,页面重新渲染. MVVM :传统的前端会将数 ...
- 【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(六)-FatFs使用的思路介绍
[STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(二)-了解SD总线,命令的相关介绍 [STM3 ...
- Oracle——概要文件profile
profile文件详解 一.目的 Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile,用它来实现对 ...
- java加密方式
加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些 ...
- shell获取目录下(包括子目录)所有文件名、路径、文件大小
一例shell脚本:取得目录下(包括子目录)所有文件名.路径与文件大小. 代码,shell脚本: lsdir.sh #!/bin/bash # #site: www.jquerycn.cn funct ...
- 使用jquery完成抽奖图片滚动的效果
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>jq ...
- java通过JDBC访问数据库(最基本的查询)
一.步骤介绍 1.通过Class.forName()加载驱动: 2.通过DriverManager.getConnection()获取Conncetion连接对象: 3.创建Statement对象传递 ...
- 【C/C++】最长公共子序列(LCS)/动态规划
晴神这个的最巧妙之处,在于用dp[i][0] = dp[0][j] = 0的边界条件 这样从1的下标开始填数组的时候,递推公式dp[i-1][j-1]之类的不会报错 #include <iost ...
- Go语言核心36讲(Go语言实战与应用二十五)--学习笔记
47 | 基于HTTP协议的网络服务 我们在上一篇文章中简单地讨论了网络编程和 socket,并由此提及了 Go 语言标准库中的syscall代码包和net代码包. 我还重点讲述了net.Dial函数 ...