数据结构第三次

6-1
List MakeEmpty()
{
    List L=(List)malloc(sizeof(struct LNode));
    if(L==NULL)
    return -1;
    #若分配内存空间失败则返回-1 
    L->Last=-1;
    #末尾元素下标用-1表示,因为此时为空 
    return L;
}
Position Find(List L,ElementType X)
{
    int i;
    for(i=0;i<=L->Last;i++)
    {
        if(L->Data[i]==X)
        #遍历,若能找到X则返回i 
        return i;
    }
    #遍历完后,若执行到这一步,说明未找到X 
    return ERROR;
}
bool Insert( List L, ElementType X, Position P )
{
    if(L->Last==MAXSIZE-1)
    {
        printf("FULL");
        #若此时L的末尾元素下标为最大值减一,则此时数组已满 
        return false;
    }
    if(P<0||P>L->Last+1)
    {
        printf("ILLEGAL POSITION");
        #若插入位置下标小于0,则非法插入,等于L->Last+1时,即在元素末尾后紧接着插入 
        return false;
    }
    int i;
    for(i=L->Last;i>=P;i--)
    {
        L->Data[i+1]=L->Data[i];
        #合法插入,执行操作 
    }
    L->Data[P]=X;
    L->Last++;
    #注意将最后元素的下标++ 
    return true;
}
bool Delete( List L, Position P )
{
    if(P<0||P>L->Last)
    {
        printf("ILLEGAL DELETION");
        return false;
        #在有元素的位置才能执行删除 
    }
    int i;
    for(i=P;i<L->Last;i++)
    {
        L->Data[i]=L->Data[i+1];
    }
    L->Last--;
    #元素末尾下标-- 
    return true;
}
6-2
List Delete( List L, ElementType minD, ElementType maxD )
{
    int slow,fast;
    #使用快慢指针的思想 
    for(slow=0,fast=0;fast<=L->Last;fast++)
    {
        if(L->Data[fast]<=minD||L->Data[fast]>=maxD)
        {
            L->Data[slow++]=L->Data[fast];
            #快指针先走并判断,符合题意得值取得,用慢指针赋值 
        }
        
    }
    L->Last=--slow;
    #slow++后应该再进行--操作 
    return L;
}
6-3
List MakeEmpty()
{
    List L=(List)malloc(sizeof(struct LNode));
    #头节点分配内存 
    if(L==NULL)return NULL;#分配失败返回NULL 
    L->Next=NULL;
    #将头节点指向NULL; 
    return L;
}
Position Find( List L, ElementType X )
{
    Position p=L->Next;
    #p指向第一个元素 
    while(p->Data!=X&&p!=NULL)
    {
        #未找到X或p仍指向链表 
        p=p->Next;
    }
    return p==NULL?ERROR:p;
    #跳出循环只有两种情况1找到X,2没找到x,p指向链表外 
}
bool Insert(List L, ElementType X, Position P) {
    Position pre=L;
    while(pre->Next!=P&&pre->Next!=NULL)
    {
        pre=pre->Next;
    }
   if(pre==NULL||pre->Next!=P)
    {
        printf("Wrong Position for Insertion\n");
        #链表为空或者待插入位置为链表头部。如果链表为空,则返回错误信息并终止插入操作或者表示待插入位置的下一个节点不是预期的 P 
        return false;
}
    Position temp=(List)malloc(sizeof(struct LNode));
    temp->Data=X;
    temp->Next=P;
    pre->Next=temp;
    return true;
}
bool Delete(List L, Position P) {
    Position pre=L;
    while(pre->Next!=P&&pre->Next!=NULL)
    {
        pre=pre->Next;
        #寻找P 
    }
    if(pre==NULL||pre->Next!=P)
    {
        #找不到女朋友“P ” 
        printf("NO FOUND");
        return false;
    }
    pre->Next=P->Next;
    free(P);
    #找到了她就放手吧 
    return true;
    
}
6-4
int FactorialSum(List L) {
    PtrToNode P=L;
    int sum=0;
    while(P!=NULL)
    {
        int jc=1;
        int i;
        for(i=1;i<=P->Data;i++)
        {
            jc*=i;
            #简单的阶乘和 
        }
        sum+=jc;
        P=P->Next;
     }
    return sum; 
}
6-5
List Merge(List L1, List L2) {
    PtrToNode dummy=(List)malloc(sizeof(struct LNode));
    #简单的合并 
    dummy->Next=NULL;
    #虚拟一个头节点,提高代码可读性和维护性 
    PtrToNode tail=dummy;
    #尾部指针,用来链接 
    PtrToNode p1=L1-Next;
    PtrToNode p2=L2->Next;
    #搞两个指针分别指向两个链表 
    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->Data<p2->Data)
        {
            tail->Next=p1;
            tail=p1;
            p1=p1->Next;
            #简单的操作 
        }
        else
        {
            tail->Next=p2;
            tail=p2;
            p2=p2->Next;
            #简单的操作 
        }
    }
    if(p1==NULL)
    {
        tail->Next=p2;
    }
    else
    {
        tail->Next=p1;
    }
    L1->Next=NULL;
    L2->Next=NULL;#这两步我觉得加不加都ok 
    return dummy; #返回头节点 
}
6-6
List Reverse( List L ){
    PtrToNode now=L;
    PtrToNode nex=NULL;
    PtrToNode pre=NULL;
    while(now!=NULL)
    {
        nex=now->Next;
        now->Next=pre;
        pre=now;
        now=nex;
        #简单的逆转操作,搞个next和prev指针就欧克    
    }
    return pre;    
}
6-7
ElementType Find( List L, int m ){
    PtrToNode slow=L;
    PtrToNode fast=L;
    int i;
    for(i=0;i<m;i++)
    {
        #链表中步长差距很有意思,这里先用fast指针走m步 
        fast=fast->Next;
        if(fast==NULL)
        return ERROR;
        #简单的判断 
    }
    while(fast!=NULL)
    {
        #然后fast和slow同时走,当fast走到NULL时,fast与slow相差m步,即slow在倒数第m个节点处 
        fast=fast->Next;
        slow=slow->Next;    
    }
    return slow->Data;#注意返回的数据类型 
}
6-8
struct ListNode *createlist() {
    struct ListNode *head=NULL;
    struct ListNode *temp,*cur;
    int num;
    while(1)
    {
        scanf("%d",&num);
        if(num=-1)
        {
            break;
        }#先判断后分配空间或者先分配空间再判断,不行就free掉,此处属于前者 
        temp=(struct ListNode*)malloc(sizeof(struct ListNode));
        temp->Data=num;
        if(head==NULL)
        {
            #判断是不是第一个元素,此时的元素是要赋值给head的 
            head->Data=temp;
            cur=temp;
        }
        else
        {
            cur->Next=temp;
            cur=temp;
        }
    }
    return head;
}
6-10
struct ListNode *deleteeven(struct ListNode *head) {
    struct ListNode * cur=head;
    struct ListNode * pre=NULL;
    while(cur!=NULL)
    {
        if(cur->Data%2==0)
        {#判断是否删除 
            if(pre==NULL)
            {
                #第一个删不删(没有头节点感觉好麻烦,有的话直接头节点的next指过去就好了,不过也都差不多) 
                head=cur->Next;
                free(cur);
                #free掉内存空间 
                cur=head;
            }
            else
            {
                pre->Next=cur->Next;
                free(cur);
                cur=pre->Next;
            }
        }
        else
        {
            pre=cur;
            cur=cur->Next;
        }
    }
    return head;
}

struct stud_node *createlist() {
    struct stud_node *head = NULL;
    struct stud_node *tail = NULL;
    struct stud_node *new;
    int num;
    while(1)
    {
        scanf("%d",&num);
        if(num==0)
        {
            break;
        }
        #先判断再分配 
        new=(struct stud_node *)malloc(sizeof(struct stud_node));
        new->Data=num;
        scanf("%s %d",new->name,&new->score);
        if(head==NULL)
        {
            head=new;
            tail=new;
        }
        else
        {
            tail->Next=new;
            tail=new;
        }#简单的创建的基本操作 
        
    }
    return head;
}
struct stud_node *deletelist(struct stud_node *head, int min_score) {
    struct stud_node *dummy=(struct stud_node *)malloc(sizeof(struct stud_node ));
    dummy->next=head;
    #创建一个虚拟的头节点 
    struct stud_node *pre=dummy;
    struct stud_node *now=head;
    while(now!=NULL)
    {
        #用now来遍历 
        if(now->num<min_score)
        {
            #如果满足条件就进行简单的删除操作 
            pre->next=now->Next;
            free(now);
            now=pre->next;
        }
        else
        {
            pre=now;
            now=now->next;
        }
    }
    head=dummy->Next;
    free(dummy);
    return head;
}
6-9
void K_Reverse(List L, int K) {
    if(K<=1||L==NULL||L->Next==NULL)
    {
        return;
        #如果反转个数<=1或为空或只有头节点 
    }
    List pre=L;
    List cur=L->Next;#cur指向第一个元素 
    List seh;#segment意为段此处用se表示seh段头set段尾nsh下一段段头 
    List set;
    List nsh;
    while(cur!=NULL)
    {
        seh=cur;
        set=cur;
        nsh=cur;
        int i;
        for(i=1;i<K&&nsh!=NULL;i++)
        {
            #注意此处留个思考题:为什么i=1,i<K呢?这样才循环k-1次 
            nsh=nsh->Next;
            if(nsh!=NULL)
            {
                set=nsh;
            }
            #判断,并将下一段段头赋值给段尾 
        }
        if(nsh==NULL)
        {
            break;
            #此时nsh==NULL说明剩余节点数不够K个 
        }
        List pre=NULL;
        List now=seh;
        List nex=NULL;
        #反转的预备操作 
        cur=nsh->Next;
        nsh->Next=NULL;
        #更新cur节点
        并将上一段段尾指向NULL 
        while(now!=NULL)
        {
                nex=now->Next;
                now->Next=pre;
                pre=now;
                now=nex;
        }
        pre->Next=set;
        #头节点指向反转后的段头(即之前的段尾) 
        seh->Next=cur;
        #反转后的段尾(即之前的段头)指向cur的地址 
        pre=seh;
        #此时的pre指向seh,当作下一段的头节点,来进行操作; 
    }
        #思考题答案:因为nsh是用nsh->Next来进行赋值的,所以少走一步刚刚好。 
}
    

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值