数据结构:线性表、链、栈、队列

数据结构:线性表、链、栈、队列

//线性表的动态分配顺序存储结构
typedef int ElemType;
struct SqList
{
    ElemType *elem; //存储空间基址
    int length;
    int listsize;
};

//单链表存储结构
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode, *LinkList;

//双向链表存储结构
typedef struct DuLNode
{
    ElemType data;
    struct DuNode *prior, *next;
}DuLNode, *DuLinkList;

//栈的顺序存储结构
typedef int SElemType;
typedef struct
{
    SElemType *base;
    SElemType *top;
}SqStack;

//单链队列存储结构
typedef int QElemType;
typedef struct QNode
{
    QElemType data;
    struct QNode *next;
} *QueuePtr;
struct LinkQueue
{
    QueuePtr front, rear;
};

//循环队列
#define MAXQSIZE 100
struct SqQueue
{
    QElemType *base; //初始化的动态分配存储空间
    int front, rear;
};

// 将所有在线性表Lb中但不在La中的数据元素插入到La中
void Union(SqList &La, SqList Lb)
 {
   ElemType e, equal;
   int La_len, Lb_len;
   int i;
   La_len = ListLength(La); // 求线性表的长度
   Lb_len = ListLength(Lb);
   for(i = 1; i <= Lb_len ;i++)
   {
     GetElem(Lb, i , e); // 取Lb中第i个数据元素赋给e
     if(!LocateElem(La , e, equal)) // La中不存在和e相同的元素,则插入之
       ListInsert(La, ++La_len, e);
   }
 }
 
 // 归并非递减线性表La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
 void MergeList_1(SqList La, SqList Lb, SqList &Lc)
 {
   int i = 1,j = 1,k = 0;
   int La_len, Lb_len;
   ElemType ai, bj;
   InitList(Lc); // 创建空表Lc
   La_len = ListLength(La);
   Lb_len = ListLength(Lb);
   while(i <= La_len && j <= Lb_len) // 表La和表Lb均非空
   {
     GetElem(La,i,ai);
     GetElem(Lb,j,bj);
     if(ai <= bj)
     {
       ListInsert(Lc, ++k, ai);
       ++i;
     }
     else
     {
       ListInsert(Lc, ++k, bj);
       ++j;
     }
   } // 以下两个while循环只会有一个被执行
   while(i<=La_len) // 表La非空且表Lb空
   {
     GetElem(La,i++,ai);
     ListInsert(Lc,++k,ai);
   }
   while(j<=Lb_len) // 表Lb非空且表La空
   {
     GetElem(Lb,j++,bj);
     ListInsert(Lc,++k,bj);
   }
 }

//归并非递减La,Lb单链表得到非递减Lc单链表
void MergeList_2(LinkList La, LinkList Lb, LinkList &Lc)
{
   LinkList pa = La->next;
   LinkList pb = Lb->next;
   LinkList pc;
   Lc = pc = La; //La的头结点作为Lc的头结点
   while(pa && pb)
   {
       if(pa->data <= pb->data)
       {
           pc->next = pa;
           pc = pa;
           pa = pa->next;
       }
       else
       {
           pc->next = pb;
           pc = pb;
           pb = pb->next;
       }
   }
   pc->next = pa ? pa : pb;
   free(Lb);
   Lb = NULL;
}

//单链表逆置
void Reverse_1(LinkList L)
{ //不带头结点
    LNode *p, *q, *r;
    p = L;
    q = NULL;
    while(p)
    {
        r = p->next;
        p->next = q;
        q = p;
        p = r;
    }
    L  = q; //L始终保持指向第一个结点
}
void Reverse_2(LinkList L)
{ //带头结点
    LNode *p, *r; //r为p的后继,以防断链
    p=L->next;
    L-next = NULL; //摘下头结点
    while(p)
    {
        r = p->next;
        p->next = L->next;
        L->next = p;
        p = r;
    }
}
void Reverse_3(LinkList L)
{ //带头结点
    LNode *pre, *p = L->next, *r = p->next;
    p->next = NULL;   //第一个结点逆置后变尾结点
    L-next = NULL;
    while(r)
    {
        pre = p;
        p = r;
        r  = r->next ;
        p->next = pre; //指针反转
    }
    L->next = p;
    return L;
}

//删除单链表最小值结点
LinkList Delete_Min(LinkList &L)
{ //带头结点
    LNode *pre = L, *p = pre-next;
    LNode *minpre = pre, *minp = p; //保存最小值结点及其前驱
    while(p)
    {
        if(p->data < minp->data)
        {
            minp = p;
            minpre = pre;
        }
        pre = p;
        p = p->next;
    }
    minpre->next = minp->next;
    free(minp);
    return L;
}

//反向输出单链表结点值
void R_Print(LinkList L)
{
    if(L->next)
        R_Print(L->next);
    print(L->data);
}

//带头结点单链表查找倒数第k个位置上的结点
Boolean Searcf_k(LinkList L, int k)
{
    LinkList *p = L->next, *q = L->next;
    int count = 0;
    while(p)
    {
        if(count < k)
        {
            count++;
            p=p->next;
        }
        else
        {
            q = q->next;
            p = p->next;
        }
    }
    if(count < k)
        return false;
    else
    {
        printf("%d", q->data);
        return true;
    }
}

//利用栈将队列元素逆置
void Inverser(Stack S, Queue Q)
{
    while(!QueueEmpty(Q))
    {
        DeQueue(Q, x);
        Push(S, x);
    }
    while(!StackEmpty(S))
    {
        Pop(S,x);
        EnQueue(Q, x);
    }
}

//将循环队列前后对称的两元素交换位置
void SqReverse(SqQueue &Q)
{
    int m, r
    m = (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
    if(front == rear)
        exit;
    f = Q.front;
    r = (Q.rear - 1 + MAXQSIZE) % MAXQSIZE
    for(i = 1; i < m / 2; ++i)
    {
        Swap(Q.base[f], Q.base[r]);
        f = (f + 1) % MAXQSIZE;
        r = (Q.rear - 1 + MAXQSIZE) % MAXQSIZE;
    }

}

//两个等长升序序列A,B,找出A和B的中位数
int M_Search(int A[], int B[], int n)
{
    int s1 =0, d1 = n-1; m1, s2 = 0, d2 = n-1, m2;
    while(s1 != d1 || s2 != d2)
    {
        m1 = (s1 + d1) / 2;
        m2 = (s2 + d2) / 2;
        if(A[m1] == B[m2])  //第一种情况
            return A[m1];
        if(A[m1] < B[m1]) //第二种情况
        {
            if((s1+d1) % 2 == 0)
            {
                s1 = m1;
                d2 = m2;
            }
            else
            {
            s1 = m1 + 1;
            d2 = m2;
            }
        }
        else //第三种情况
        {
            if((s1 + d1) %2 == 0)
            {
                d1 = m1;
                s2 = m2;
            }
            else
            {
                d1 = m1;  s2 = m1;
            }
        }
    }
    return A[s1] < B[s2] ? A[s1] : B[s2];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值