[数据结构]链表LinkList

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;
}

posted @ 2021-03-03 17:15  Xu_Lin  阅读(316)  评论(0编辑  收藏  举报