数据结构--单链表

/***************************************************************************
 * File: LINKLIST.h
 * Author: suzhaoda ([email protected])
 *
 * 单链表
 * ADT (List)
 * Data
 *   {a1, a2, a3, ..., an}
 * Operation
 *   InitList(*L, n, Method);   初始化,按Method建立一个n元素值的单链表L.
 *   ListEmpty(L);              如果单链表L为空,返回true,否则返回false.
 *   ClearList(*L);             将单链表L清空.
 *   GetElem(L, i, *e);         将单链表L中第i个位置元素值返回给e.
 *   LocateElem(L, e);          在L查找和e相等的元素,成功返回元素所在的.
 *                              序号,否则,返回0表示失败.
 *   ListInsert(*L, i, e);      在L中第i个位置插入新元素e.
 *   ListDelete(*L, i, *e);     删除L中第i个位置的元素,并用e返回其值.
 *   ListLength(L);             返回线性表L的元素个数.
 * ENDADT
 * 逻辑结构
 *                   |a1| |  |a2|  | ...|ai|  | ...|an|^ |
 *                     |       ^  |       ^  |       ^
 *                     |_______|  |_______|  |_______|
 *
 * 修改记录:
 *           2012-12-17 重新组织代码,编译调试,修正语法错误.
 */

#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED

/************************ data   单链表存储结构定义 ************************/
#include <stdlib.h>             /* malloc() rand() srand()*/
#include <time.h>               /* time() */

#define OK    1
#define ERROR 0
#define TRUE  1
#define FALSE 0

typedef int ElemType;           /* ElemType 类型根据实际情况而定,现假设为 int */
typedef int Status;             /* Status 是函数的类型,其值是函数结果状态代码 */

typedef enum{
  HEAD,
  TAIL
}CreateMethod;                  /* CreateMethod 创建单链表的方法,头插入和为插入法 */

/* 单链表的存储结构 */
typedef struct Node {
  ElemType data;
  struct Node* next;
} Node;

/* 定义LinkList */
typedef struct Node* LinkList;

/***************************** operation 操作 *****************************/

/*
 * 初始条件:单链表L不存在.
 * 操作结果:随机生成n个元素的值,建立带表头节点的单链表L(头插入法)
 */
void CreateListHead(LinkList* L, int n);

/*
 * 初始条件:单链表L不存在
 * 操作结果:随机生成n个元素的值,建立带表头节点的单链表L(尾插入法)
 */
void CreateListTail(LinkList* L, int n);

/*
 * 初始条件:单链表L不存在;
 * 操作结果:初始化,建立n个元素的单链表L;
 */
Status InitList(LinkList* L, int n, CreateMethod Method);

/*
 * 初始条件:单链表L已存在
 * 操作结果:如果单链表为空,返回true,否则返回false
 */
Status ListEmpty(LinkList L);

/*
 * 初始条件:单链表L已存在,1 <= i <= ListLength(L)
 * 操作结果:用e返回L中第i个元素的值
 */
Status GetElem(LinkList L, int i, ElemType* e);

/*
 * 初始条件: 单链表L已存在。
 * 操作结果:将单链表重置为空表。
 */
Status ClearList(LinkList* L);

/*
 * 初始条件:单链表L已存在.
 * 操作结果:在L查找和e相等的元素,成功返回元素所在的序号,
 *           否则,返回0表示失败
 */
int LocateElem(LinkList L, ElemType e);

/*
 * 初始条件: 单链表L已存在,1 <= i <= ListLength(L)
 * 操作结果:在L中第i个位置之前插入新元素e , L的长度加1
 */
Status ListInsert(LinkList* L, int i, ElemType e);

// LINKLIST.h
/*
 * 初始条件: 单链表L已存在,1 <= i <= ListLength(L)
 * 操作结果:在L中第i个位置之前插入新元素e , L的长度加1
 */
Status ListDelete(LinkList* L, int i, ElemType e);

/*
 * 初始条件:单链表L已经存在.
 * 操作结果:返回单链表L的元素个数.
 */
int ListLength(LinkList L);

#endif // LINKLIST_H_INCLUDED

//LINKLIST.C


#include "LINKLIST.h"

void CreateListHead(LinkList* L, int n)
{
  LinkList p;
  int i;

  srand(time(0));         /* 初始化随机种子 */

  (*L) = (LinkList)malloc(sizeof(Node));
  (*L) -> next = NULL;    /* 先建立一个带头节点的单链表 */

  for(i = 0; i < n; i++){
    p = (LinkList) malloc(sizeof(Node));  /* 生成新节点 */
    p -> data = rand() % 100 + 1;         /* 生成100以内的数字 */
    p -> next = (*L) -> next;
    (*L) -> next = p;                     /* 插入到表头 */
  }
}

void CreateListTail(LinkList* L, int n)
{
  LinkList p;
  LinkList r;
  int i;

  srand(time(0));         /* 初始化随机种子 */

  (*L) = (LinkList)malloc(sizeof(Node));
  r = *L;                 /* r为指向尾的节点 */

  for(i = 0; i < n; i++){
    p = (LinkList) malloc(sizeof(Node));
    p -> data = rand() % 100 + 1;         /* 生成100以内的数字 */
    r -> next = p;                        /* 将表尾终端节点的指针指向新的节点 */
    r = p;                                /* 将当前的新节点定义为表尾终端节点 */
  }

  r -> next = NULL;
}

Status InitList(LinkList* L, int n, CreateMethod Method)
{
   switch (Method) {
     case HEAD : CreateListHead(L, n);break;
     case TAIL : CreateListTail(L, n);break;
     default   : return FALSE;
   }
   return OK;
}

Status ListEmpty(LinkList L)
{
  return (L -> next == NULL ? TRUE : FALSE);
}

Status GetElem(LinkList L, int i, ElemType* e)
{
  int j;
  LinkList p;        /* 声明一个结点 */

  p = L -> next;     /* 让p指向L的第一个节点 */
  j = 1;             /* j为计数器 */

  /* p不为空并且计数器j还没到i时,循环继续 */
  while (p && j < i) {
    p = p -> next;   /* 让p指向下一个节点 */
    j++;
  }

  if (!p || j > i)   /* 第i个元素不存在 */
    return ERROR;

  *e = p -> data;    /* 取第i个元素 */

  return OK;
}

Status ClearList(LinkList* L)
{
  LinkList p;
  LinkList q;

  p = (*L) -> next;

  while(p){           /* 没到表尾 */
    q = p -> next;
    free(p);
    p = q;
  }

  (*L) -> next = NULL;  /* 头节点的指针域为空 */
  return OK;
}

int LocateElem(LinkList L, ElemType e)
{
  int i;
  LinkList p;
  p = L -> next;     /* 指向链表第一个元素 */
  i = 1;             /* i为计数器 */

  /* 此处可以使用更快的算法 */
  while(p != NULL){  /* p没有指向链表尾部则继续循环 */

    if(p ->data == e)
      return i;
    i++;
    p = p -> next;
  }
  return 0;
}

Status ListInsert(LinkList* L, int i, ElemType e)
{
  int j;
  LinkList p;
  LinkList s;

  p = *L;        /* L是指针的指针 */
  j = 1;

  /* 寻找第i个节点 */
  while(p && j < i){
    p = p -> next;
    j++;
  }

  /* 第i个节点不存在 */
  if (!p || j > i)
    return ERROR;

  /* 生成新节点 */
  s = (LinkList) malloc(sizeof(Node));
  s -> data = e;

  s -> next = p -> next;    /* 将p的后继赋给s */
  p -> next = s;            /* 将s作为p后继 */

  return OK;
}

Status ListDelete(LinkList* L, int i, ElemType* e)
{
  int j;
  LinkList p;
  LinkList q;

  p = *L;        /* L是指针的指针 */
  j = 1;

  /* 寻找第i个节点 */
  while(p -> next && j < i){
    p = p -> next;
    j++;
  }

  /* 第i个节点不存在 */
  if (!(p -> next) || j > i)
    return ERROR;

  q = p -> next;
  p -> next = q ->next;  /* 将q的后继赋给p的后继 */
  *e = q -> data;        /* 将q节点中的数据给e */
  free(q);               /* 让系统会收节点,释放内存 */

  return OK;
}

int ListLength(LinkList L)
{
  int i;
  LinkList p;

  i = 0;
  p = L -> next;

  while (p){
    i++;
    p = p -> next;
  }

  return i;
}

参考<大话数据结构>

你可能感兴趣的:(数据结构,C语言,单链表)