郝斌数据结构4(链表程序)

链表实现

算法
狭义的算法:与数据的存储方式密切相关
广义的算法:与数据的存储方式无关
泛型
(给你一种假象,只不过牛人从内部都弄好了)
利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的
算法的真正学法:
  很多算法你根本解决不了!!!!!!因为很多都属于数学上的东西,所以我们把答案找出来,如果能看懂就行。
  但是大部分人又看不懂,分三步走
  1.梳理流程
  2.搞懂每一个语句功能
  3.试数,拿数据进行推理,
  这个过程肯定会不断地出错,所以不断出错,不断改错,这样反复敲很多次,才能有个提高。极端情况下,实在看不懂就先背会。

链表的优缺点:
  优点:
    空间没有限制
    插入删除元素很快
  缺点:
    存取速度很慢。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<stdbool.h>

typedef struct Node
{
    int data;
    struct Node * pNext;
}NODE, * PNODE;
//创建链表,此处使用的是尾插法,还有一种类似的头插法
PNODE creat_list()
{
    int len = 0;
    int i = 0;
    int val = 0;
    PNODE pHead = (PNODE) malloc(sizeof(NODE));
    if(NULL == pHead)
    {   
        printf("malloc err!\n");
        exit(-1);
    }   
    PNODE pTail = pHead;
    pTail->pNext = NULL;
    
    printf("请输入您需要创建的链表节点的个数:len = ");
    scanf("%d",&len);

    for(i = 0; i < len; i++)
    {   
        printf("请输入第%d个节点的数据:val = ",i+1);
        scanf("%d",&val);

        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if(NULL == pNew)
        {
            printf("分配失败,程序终止!\n");
            exit(-1);
        }
        pNew->data = val;
        pTail->pNext = pNew;
        pNew->pNext = NULL;//这句其实没必要,只需要创建完成在尾节点指针域赋值为NULL即可
        pTail = pNew;
    }
    //pTail->pNext = NULL;//尾节点指针为空
    return pHead;
}
//判断链表是否为空
bool is_empty(PNODE pHead)
{
    if(NULL == pHead->pNext)
        return true;
    else
        return false;
}
//遍历链表并输出
void traverse_list(PNODE pHead)
{
    if(is_empty(pHead))
    {
        printf("链表为空!\n");
        return;
    }
    PNODE p = pHead->pNext;
    while(p != NULL)
    {   
        printf("%d\t", p->data);
        p = p->pNext;
    }   
    printf("\n");
    return;
}
//求链表长度
int length_list(PNODE pHead)
{
    PNODE p = pHead;
    int i = 0;
    while(p->pNext != NULL)
    {
        i++;
        p = p->pNext;
    }
    return i;
}
//链表排序
void sort_list(PNODE pHead)
{
    PNODE p,q;
    int t;
    int i,j;
    for(i = 0, p = pHead->pNext; i < len, p != NULL; i++, p = p->pNext)
        for(i = j+1, q = p->pNext; j < len, q != NULL; j++, q = q->pNext)
        {
            if(p->data > q->data)//a[i] > a[j]
            {
                t = p->data;      //t = a[i];
                p->data = q->data;//a[i] = a[j];
                q->data = t;      //a[j] = t;
            }
        }
    return;
}
//插入节点,特别注意while中与删除节点的区别
//插入节点while判断使用的是p,因为即使是链表为空,只有头结点,也可以在头结点后插入一个节点
//删除节点while判读使用的是p->pNext,因为链表为空的时候,没有节点可以删除
int insert_list(PNODE pHead, int pos, int val)
{
   int i;
   PNODE p = pHead;
    //首先调整p指向的位置,
   while(NULL != p && i < pos - 1)//注意此处用的是p
   {
       p = p->pNext;
       i++;
   }
    //这时候p已经指向pos的位置
   if(i > pos-1 || p == NULL)
       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;
}

int delete_list(PNODE pHead, int pos, int *val)
{
    int i = 0;
    PNODE p = pHead;

    while (NULL!=p->pNext && i<pos-1)//此处使用的p->pNext
    {
        p = p->pNext;
        ++i;
    }
    
    if (i>pos-1 || NULL==p->pNext)
       return false;

    PNODE q = p->pNext;
    *val = q->data;
    p->pNext = q->pNext;
    free(q);
    return true;
}
int main(void)
{
    PNODE pHead;
    pHead = creat_list();
    traverse_list(pHead);
    //if(is_empty(pHead))
      //  printf("list is empty!\n");
    printf("list length:%d\n",length_list(pHead));
    sort_list(pHead);
    traverse_list(pHead);
    int ret;
    /* ret = insert_list(pHead, 1, 11);
    if(ret < 0)
    {
        printf("插入失败,ret = %d\n",ret);
        return -1;
    }
    traverse_list(pHead);*/
    int val;
    int pos;
    printf("请输入您要删除的节点位置pos(pos从1开始): ");
    scanf("%d",&pos);

    ret = delete_list(pHead, pos, &val);
    if(ret != 1)
        printf("删除失败!\n");
    else
        printf("删除节点数据:val %d\n",val);
    traverse_list(pHead);

    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值