6.离散结构-链表【郝斌数据结构】

离散存储:链表

1.定义:

  n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点。

  首节点没有前驱节点,尾节点没有后续节点。

  专业术语:

  首节点:第一个有效节点

  尾节点:最后一个有效节点

  头结点:

      头结点的数据类型和首节点类型一样

      第一个有效节点之前的那个节点

      头结点并不存放有效数据

      加头结点的目的主要是为了方便对链表的操作

  头指针:指向头结点的指针变量

  尾指针:指向尾节点的指针变量

 

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

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

2.分类:

  单链表:

  双链表:每一个节点有两个指针域

  循环链表:能通过任何一个节点找到其他所有结点

  非循环链表:

3.算法:

   (1)遍历

   (2)查找

   (3)清空

   (4)销毁

   (5)求长度

   (6)排序

   (7)删除节点

删除节点图解:

 

   (8)插入节点

插入节点图解:

 

    算法:狭义的算法是与数据的存数方式密切相关;

       广义的算法是与数据的存储方式无关;

    泛型:

      利用某种技术达到的效果就是:用不同的存数方式,执行的操作是一样的

链表的源程序:

 

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct Node
{
    int data;//数据域
    struct Node * pNext;//指针域
}NODE, *PNODE;//NODE等价于struct Node, PNODE等价于struct Node *
//函数声明
PNODE create_list(void);
void traverse_list(PNODE pHead);
bool is_empty(PNODE pHead);
int length_list(PNODE pHead);
bool insert_list(PNODE pHead, int pos, int val);
bool delete_list(PNODE pHead, int pos, int * pval);
void sort_list(PNODE pHead);
int main(void)
{
    PNODE  pHead = NULL;//等价于struct Node * pHead = NULL;
    int val;
    //creat_list()功能:创建一个非循环单链表,单链表的头结点地址赋给pHead
    pHead = create_list();
    traverse_list(pHead);
    if (is_empty(pHead))
        printf("列表为空!\n");
    else
        printf("列表不为空!\n");
    int len = length_list(pHead);
    printf("链表的长度为:%d\n", len);
    sort_list(pHead);
    traverse_list(pHead);
    insert_list(pHead, 3, 28);
    traverse_list(pHead);
    delete_list(pHead, 4, &val);
    traverse_list(pHead);
    return 0;
}
//创建链表
PNODE create_list(void)
{
    int len;//用来存储有效节点的个数
    int i;
    int val;//用来临时存放用户输入的节点值
    //分配了一个不存放有效数据的头结点
    PNODE pHead = (PNODE)malloc(sizeof(NODE));
    if (NULL == pHead)
    {
        printf("分配失败,程序终止!\n");
        exit(-1);
    }
    PNODE pTail = pHead;
    pTail->pNext = NULL;
    printf("请输入你需要生成链表节点的个数:len=");
    scanf("%d",&len);
    for (i=0;i<len;++i)
    {
        printf("请输入第%d个节点的值:", i+1);
        scanf("%d", &val);
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if (NULL == pNew)
            {
                printf("分配失败,程序终止!\n");
                exit(-1);
            }
        pNew->data = val;
        pTail->pNext = pNew;
        pTail = pNew;
        pTail->pNext = NULL;
    }
    return pHead;
}
//遍历链表
void traverse_list(PNODE pHead)
{
    PNODE p;
    p = pHead->pNext;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->pNext;
    }
    printf("\n");
    return;
}
//判断列表是否为空
bool is_empty(PNODE pHead)
{
    if (NULL == pHead->pNext)
        return true;
    else
        return false;
}
//求列表的长度
int length_list(PNODE pHead)
{
    PNODE p = pHead->pNext;
    int len = 0;
    while (NULL != p)
    {
        ++len;
        p = p ->pNext;
    }
    return len;    
}
//排序
void sort_list(PNODE pHead)
{
    int i, j, t;
    int len=length_list(pHead);
    PNODE p, q;
    for (i=0,p=pHead->pNext; i<len-1; ++i,p=p->pNext)
    {
            for(j=i+1,q=p->pNext; j<len; ++j,q=q->pNext)
            {
                if(p->data > q->data )
                {
                    t = p->data;
                    p->data = q->data;
                    q->data = t;
                }
            }
    }
/*    数组的选择排序
   int i, j, t;
   for(i=0;i<len-1; ++i)
    {
        for(j=i+1; j<len; ++j)
        {
            if (a[i]>a[j])
            {
                t=a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
    }
*/
}
//咋pHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且pos值从1开始
bool insert_list(PNODE pHead, int pos, int val)
{
    int i=0;
    PNODE p = pHead;
    while(p!=NULL && i<pos-1)
    {
        p=p->pNext;
        ++i;
    }
    if (i>pos-1 || NULL==p)
        return false;
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if (NULL == pNew)
    {
        printf("动态内存分配失败!\n");
        exit(-1);
    }
    pNew->data = val;
    PNODE q = p->pNext;
    p->pNext=pNew;
    pNew->pNext=q; 
    return true;
}
//删除第pos个节点
bool delete_list(PNODE pHead, int pos, int * pval)
{
    int i=0;
    PNODE p = pHead;
    while(p->pNext!=NULL && i<pos-1)
    {
        p=p->pNext;
        ++i;
    }
    if (i>pos-1 || NULL==p->pNext)
        return false;
    PNODE q = p->pNext;
    *pval = q->data;
    //删除p节点后面的节点
    p->pNext = p->pNext->pNext;
    free(q);
    q=NULL;
    return true;    
}

 

4.链表的优缺点:

posted @ 2024-08-27 06:00  java帝国  阅读(23)  评论(0)    收藏  举报