链表

离散存储–链表

定义:

  1. n 个结点离散分配
  2. 彼此通过指针相连
  3. 每个结点只有一个前驱结点,每个结点只有一个后继结点。
  4. 首结点没有前驱结点,尾结点没有后继结点

专业术语:

  1. 首结点

    第一个有效结点

  2. 尾结点

    最后一个有效结点

  3. 头结点

    第一个有效结点前的那个结点头结点不存放有效数据
    加头结点的目的主要是为了方便对链表的操作

  4. 头指针

    指向头结点的指针变量

  5. 尾指针

    指向尾结点的指针变量

如果希望通过一个函数来对链表进行处理,我们至少需要接收链表的哪些参数:

只需要一个参数:头指针  
因为我们通过头指针可以推算出链表的其他所有信息。

构建一个结点:

1
2
3
4
5
6
typedef struct Node
{
int data; //数据域
struct Node * pNext; //指针域
}* PNODE,NODE; //NODE等价于struct Node,
//PNODE等价于struct Node *

分类:

  1. 单链表
  2. 双链表:

    每个结点有两个指针域

  3. 循环链表:

    能通过任何一个结点找到其他所有结点

  4. 非循环链表

单链表算法:

1
2
3
4
5
6
7
定义链表结点:
typedef int ElemType //不一定是int型,ElemType是需求类型
typedef struct LNode
{
ElemType data; //存放元素值
struct LNose * next; //指向后继结点
}LinkNode; //单链表结点类型
初始化 InitList(&L)

void InitList(LinkNode *&L)
{
    L = (LinkNode *)malloc(sizeof(LinkNode));
    L->next s= NULL;
}
销毁 DestroyList(&L)

void DestoryList(LinkNode *&L)
{
    LinkNode * pre = L,*p = L->next;
    while(p != NULL)
    {
        free(pre);
        pre = p;
        p = pre->next;
    }
    free(pre);
}
判空 ListEmpty(L)

bool ListEmpty(LinkNode * L)
{
    return(L->next = NULL);
}
求长度 ListLength(L)

int ListLength(LinkNode * L)
{
    LinkNode * p = L;
    int n=0;
    while(p->next != NULL)
    {
        n++;
        p = p->next;
    }
    return(n);
}

输出 DispList(L)

void DispList(LinkNode * L)
{
    LinkNode *p = L->next;
    while(p != NULL)
    {
        printf("%d\n",p->data);
        p = p->next;
    }
    printf("\n");
}
按位求值 GetElem(L,i,&e)

bool GetElem(LinkNode *L,int i, ElemType &e)
{
    int j = 0;
    LinkNode *p = L;
    if (i <= 0) return false; while(j < i && p !="NULL)" { j++;>next;
    }
    if(p == NULL)
        return false;
    else
    {   
        e = p->data;
        return true;
    }
}
按值查找 LocateElem(L,e)

int LocateElem(LinkNode *L,ElemType e)
{
    int i = 1;
    LinkNode *p = L-> next;
    while(p != NULL && p->data != e)
    {
        p = p-> next;
        i++;
    }
    if(p == NULL)
        return 0;
    else
        return (i);
}
插入数据 ListInsert(&L,i,e)

bool ListInsert(LinkNode *&L,int i,ElemType e)
{
    int j = 0;
    LinkNode *p = L,*s;
    if(i <= 0) return false; while(j < i-1 && p !="NULL)" { j++;>next;
    }
    if(p == NULL)
        return false;
    else
    {
        s = (LinkNode *)malloc(sizeof(LinkNode));
        s->data =e ;
        s->next = p->next;
        p->next = s;
        return true;
    }
}
删除数据 ListDelete(&L,i,&e)

bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
    int j = 0;
    LinkNode *p = L,*q;
    if (i <= 0) return false; while (j < i-1 && p !="NULL" ) { j++;>next;
    }
    if (p == NULL)
        return false;
    else
    {
        q = p->next;
        if(q == NULL)
            return false;
        e = q->data;
        p->next = q->next;
        free(q);
        return true;
    }
}
-------------本文结束感谢您的阅读-------------