C和指针第十二章编程练习

这篇博客主要介绍了C语言中关于链表的编程练习,包括如何遍历链表以及适用于无序和有序链表的操作。内容涵盖多个练习点,旨在提升读者对链表操作的理解和实践能力。
摘要由CSDN通过智能技术生成

12.8.1
必须知道链表类型 修改改函数可用于遍历链表

typedef struct list
{
    int i;
    struct list * n;
}List;
int listcount(List * d)
{
    int count = 0;
    while(d->n)
    {
        count++;
        d = d->n;
    }
    return count;
}

12.8.2
无序有序都可以用这个

List * find(int a, List * b)
{
    while(b->n)
    {
        if(b->i == a)
            return b;
        b = b->n;
    }
    return NULL;
}

12.8.3

int dll_insert(register Node * head, register Node * trail, int value)
{
    Node * current, * next, * news;
    for(current = head; (next = current->fwd); current = next)
    {
        if(current->value == value)
            return 0;
        if(current->fwd->value > value)
            break;
    }
    news = (Node *)malloc(sizeof(Node));
    if(!news)
        return -1;
    news->value = value;
    news->fwd = next;
    current->fwd = news;
    if(current == head)
        news->bwd = NULL;
    else
        news->bwd = current;
    if(next)
        next->bwd = news;
    return 1;
}

12.8.4

struct NODE
{
   int i;
   struct NODE * n;
};
struct NODE * sll_reverse(struct NODE * first)
{
    if(!first)
        return NULL;
    int count = 0;
    struct NODE * temp, * temp1, *temp2, * head;
    temp2 = first;
    while(temp2)
    {
        count++;
        if(!temp2->n)
            head = temp2;
        temp2 = temp2->n;
    }
    int i;
    for(i = 0, temp2 = first; i < count - 1; i++, temp2 = first)
    {
        while(temp2->n)
        {
            temp = temp2;
            temp1 = temp2->n;
            temp2 = temp2->n;
        }
        temp1->n = temp;
        temp->n = NULL;
    }
    return head;
}

12.8.5

int sll_remove(struct NODE ** rootp, struct NODE * node)
{
    struct NODE * temp = *rootp, * temp1;
    while(temp)
    {
        if(temp == node)
        {
            temp1 = temp;
            *rootp = temp->n;
            free(temp);
            return 1;
        }
        else if(temp->n == node)
        {
            temp1 = temp->n;
            break;
        }
        temp = temp->n;
    }
    if(!temp)
        return 0;
    if(temp1->n)
        temp->n = temp1->n;
    else
        temp->n = NULL;
    free(temp1);
    return 1;
}

12.8.6

struct NODE
{
   int i;
   struct NODE * l;
   struct NODE * r;
};
int dll_remove(struct NODE * rootp, struct NODE * node)
{
    struct NODE * temp = rootp->r, * temp1;
    while(temp)
    {
        if(temp == node)
        {
            temp1 = temp->r;
            free(temp);
            temp1->l = NULL;
            rootp->r = temp1;
            return 1;
        }
        else if(temp->r == node)
        {
            temp1 = temp;
            temp = temp->r;
            break;
        }
        temp = temp->r;
    }
    if(!temp)
        return 0;
    if(temp->r)
    {
        temp1->r = temp->r;
        temp->r->l = temp1;
    }
    else
        temp1->r = NULL;
    free(temp);
    return 1;
}

12.8.7
应该没问题吧

int indexinsert(struct index ** rootp, char * str)
{
    if(*str < 'a' || *str > 'z')
        return 0;
    int sign = 0;//标志
    struct index * temp = *rootp;//首先创建一个临时变量存储第一个索引节点
    struct world * temp1 = (*rootp)->prese;//temp1存储第一个索引节点的第一个单词节点
    struct world * temp2, * temp3 = temp1;//temp2用于插入节点使用temp3保存第一个单词节点
    while(temp)//判断是不是到了最后一个节点
    {
        if(temp->ch == *str)//判断节点的索引是否与欲操作的字符串首字母相同
        {//如果相同
            if(!temp1)//如果当前索引节点的第一个单词节点为NULL
            {
                temp->prese = (struct world *)malloc(sizeof(struct world));//就给一个索引节点的第一个单词节点创建内存
                temp->prese->str = str;//赋值欲操作的字符串到指定位置
                temp->prese->next = NULL;//然后让该节点的下一个节点为NULL表示这是最后一个
                sign = 1;
                break;
            }
            else//如果当前索引节点的第一个单词节点不为NULL
            {
                while(temp1)//先查这个单词节点里面所有单词是否与欲操作字符串相同
                {
                    if(strcmp(temp1->str, str) == 0)//有相同直接返回
                        return 0;
                    temp1 = temp1->next;//没找到继续下一个
                }
                temp1 = temp3;//全部找完没有返回证明没有找到
                while(temp1)//判断该单词节点不为NULL就继续循环
                {
                    if(strcmp(str, temp1->str) > 0)//如果目标字符串大于节点中字符串
                    {
                        temp3 = temp1;//保存此时的temp1
                        if(!temp1->next)//判断temp1下一个是否为NULL
                        {//如果为NULL
                            temp1->next = (struct world *)malloc(sizeof(struct world));
                            temp1->next->str = str;
                            temp1->next->next = NULL;
                            sign = 1;
                            break;
                        }
                        else//否则继续往下判断
                            temp1 = temp1->next;
                    }
                    else//目标字符串小于节点中字符串
                    {
                        temp2 = (struct world *)malloc(sizeof(struct world));
                        temp2->str = str;
                        temp2->next = NULL;
                        if(!temp3->next)
                            temp3->next = temp2;
                        else if(temp1 == (*rootp)->prese)//temp3为前一个节点 temp2为新节点 temp1为后一个节点
                        {
                            (*rootp)->prese = temp2;
                            temp2->next = temp1;
                        }
                        else
                        {
                            temp2->next = temp1;
                            temp3->next = temp2;
                        }
                        sign = 1;
                        break;
                    }
                }
            }
        }
        if(sign)
            break;
        temp = temp->next;
        temp1 = temp->prese;
        temp3 = temp1;
    }
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值