[数据结构]链表

Feb 10, 2015


①线性表的本质:

线性表的定义:

线性表(List)是零个或多个数据元素的集合、线性表中的数据元素之间是有顺序的、线性表中的数据元素个数是有限的、线性表中的数据元素的类型必须相同

②线性表的相关操作:

线性表的一些常用操作:创建线性表、销毁线性表、清空线性表、将元素插入线性表、将元素从线性表中删除、获取线性表中某个位置的元素、获取线性表的长度

图片\

下面给出一个实例,创建链表,并遍历链表:


#include <stdlib.h>  
#include <stdio.h>  
  
struct node  
{  
    int num;  
    struct node *next;  
};  
  
int Number;  
  
struct node*creat(struct node *head, struct node*pNew, struct node*pEnd)  
{  
    pNew->next = NULL;  
  
    int i = 1;  
    while (i<=Number)  
    {  
        if (head == NULL)  
        {  
            printf("NO%d\n",i);  
            head = pNew;  
            printf("pHead=%d\n", head);  
            pEnd = pNew;  
            printf("pEnd=%d\n", pEnd);  
            pEnd->next = pNew->next;  
            printf("pEnd->next=%d\n", pEnd->next);  
            printf("/**********************/\n");  
        }  
        else  
        {  
            printf("NO%d\n", i);  
            pNew = (struct node*)malloc(sizeof(struct node));  
            pNew->next = NULL;  
            pEnd->next = pNew;  
            printf("pNew=%d\n",pNew);  
            pEnd = pNew;  
            printf("pEnd=%d\n", pEnd);  
            pEnd->next = pNew->next;  
            printf("pEnd->next=%d\n", pEnd->next);  
            printf("/**********************/\n");  
        }  
        ++i;  
    }  
    return head;  
}  
  
void print(struct node*head)  
{  
    int i = 1;  
    struct node *temp;  
    temp = head;  
    while (temp != NULL)  
    {  
        printf("NO%d\n", i);  
        ++i;  
        printf("temp=%d\n", temp);  
        printf("temp->next=%d\n", temp->next);  
        temp = temp->next;  
        printf("/**********************/\n");  
    }  
}  
  
main()  
{  
    printf("please input number !\n");  
    scanf_s("%d", &Number);  
  
    struct node *head;  
    struct node*pNew, *pEnd;  
    pNew = pEnd = (struct node*)malloc(sizeof(struct node));  
    head = NULL;  
    head = creat(head,pNew,pEnd);  
    print(head);  
    printf("finally\n");  
}  

输入数字5,创建含有5个节点的链表:

图片

③线性表的顺序存储结构:

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

优点:

无需为线性表中的逻辑关系增加额外的空间、可以快速的获取表中合法位置的元素

缺点:

插入和删除操作需要移动大量元素、当线性表长度变化较大时难以确定存储空间的容量

下面给出一个实例,创建链表,并遍历链表,并进行增加节点,删除节点,查找节点操作:


#include <stdlib.h>  
#include <stdio.h>  
  
struct node  
{  
    int num;  
    struct node *next;  
};  
  
int Number;  
  
struct node*creat(struct node *head, struct node*pNew, struct node*pEnd)  
{  
    pNew->next = NULL;  
  
    int i = 1;  
    while (i<=Number)  
    {  
        if (head == NULL)  
        {  
            printf("NO%d\n",i);  
            head = pNew;  
            printf("pHead=%d\n", head);  
            pEnd = pNew;  
            printf("pEnd=%d\n", pEnd);  
            pEnd->next = pNew->next;  
            printf("pEnd->next=%d\n", pEnd->next);  
            printf("/**********************/\n");  
        }  
        else  
        {  
            printf("NO%d\n", i);  
            pNew = (struct node*)malloc(sizeof(struct node));  
            pNew->next = NULL;  
            pEnd->next = pNew;  
            printf("pNew=%d\n",pNew);  
            pEnd = pNew;  
            printf("pEnd=%d\n", pEnd);  
            pEnd->next = pNew->next;  
            printf("pEnd->next=%d\n", pEnd->next);  
            printf("/**********************/\n");  
        }  
        ++i;  
    }  
    return head;  
}  
  
void print(struct node*head)  
{  
    int i = 1;  
    struct node *temp;  
    temp = head;  
    while (temp != NULL)  
    {  
        printf("NO%d\n", i);  
        ++i;  
        printf("temp=%d\n", temp);  
        printf("temp->next=%d\n", temp->next);  
        temp = temp->next;  
        printf("/**********************/\n");  
    }  
}  
  
void nodeFind(struct node*head)  
{  
    int i=1,x=0;  
    printf("please input the find node Number:\n");  
    scanf_s("%d",&x);  
    struct node *temp;  
    temp = head;  
    while (temp != NULL)  
    {  
        if (i == x)  
        {  
            printf("NO%d\n", i);  
            ++i;  
            printf("temp=%d\n", temp);  
            temp = temp->next;  
            printf("/**********************/\n");  
            return;  
        }  
        else  
        {  
            ++i;  
            temp = temp->next;  
        }  
    }  
    printf("the node Number is out range!\n");  
    printf("/**********************/\n");  
}  
  
void addnode(struct node*head)  
{  
    int i = 1, x = 0;  
    printf("please input the add node Number:\n");  
    scanf_s("%d", &x);  
    struct node *temp;  
    struct node *newnode;  
    temp = head;  
    newnode = (struct node*)malloc(sizeof(struct node));  
    newnode->next = NULL;  
    while (temp != NULL)  
    {  
        if (i == (x-1))  
        {  
            newnode->next = temp->next;  
            temp->next = newnode;  
            return;  
        }  
        else  
        {  
            ++i;  
            temp = temp->next;  
        }  
    }  
    printf("the add node Number is out range!\n");  
    printf("/**********************/\n");  
}  
  
void delnode(struct node*head)  
{  
    int i = 1, x = 0;  
    printf("please input the delete node Number:\n");  
    scanf_s("%d", &x);  
    struct node *temp;  
    struct node *delnode;  
    temp = head;  
    delnode = (struct node*)malloc(sizeof(struct node));  
    delnode->next = NULL;  
    while (temp != NULL)  
    {  
        if (i == (x - 1))  
        {  
            delnode= temp->next;  
            delnode = delnode->next;  
            temp->next = delnode;  
            return;  
        }  
        else  
        {  
            ++i;  
            temp = temp->next;  
        }  
    }  
    printf("the add node Number is out range!\n");  
    printf("/**********************/\n");  
}  
  
void main()  
{  
    printf("please input number !\n");  
    scanf_s("%d", &Number);  
  
    struct node *head;  
    struct node*pNew, *pEnd;  
    pNew = pEnd = (struct node*)malloc(sizeof(struct node));  
    head = NULL;  
    head = creat(head,pNew,pEnd);  
    print(head);  
    nodeFind(head);  
    addnode(head);  
    print(head);  
    delnode(head);  
    print(head);  
    printf("finally\n");  
}  

创建节点:

图片

遍历链表:

图片

查找指定节点:

图片

增加节点:

图片

删除节点:

图片

④链式存储逻辑结构:

n个结点链接成一个链式线性表的结构叫做链表,当每个结点中只包含一个指针域时,叫做单链表。

⑤静态链表的逻辑结构:

静态链表是在顺序表的基础上利用数组实现的单链表!

⑥循环链表:

循环链表只是在单链表的基础上做了一个加强、循环链表可以完全取代单链表的使用、循环链表的Next和Current操作可以高效的遍历链表中的所有元素

⑦双向链表:

单链表的结点都只有一个指向下一个结点的指针、单链表的数据元素无法直接访问其前驱元素逆序访问单链表中的元素是极其耗时的操作!