链表的运用

链表

1.双向链表

四个数据项

  • 前指针 pre
  • 后指针 next
  • 数据 data
  • 访问频度 frequent
    问题: 每个数据的初始频度都为0,在该链表中查找x,若访问到,就将该结点的频度+1,然后将该链表按频度从大到小排列

代码:
定义语句:

typedef struct Node{
    int frequent;
    int data;
    struct Node *next;
    struct Node *pre;
}Node,*LinkList;

初始化

int InitList(LinkList *L){
    LinkList root = (LinkList)malloc(sizeof(Node));
    root->next = NULL;
    root->pre = NULL;
    *L = root;
    return 1;
}

插入方法

int ListInsert(LinkList *L,int n,int data){
    int i = 1;
    LinkList p,m;
    p = *L;  //p的初始为头结点,方便对第一个结点进行插入
    while(i < n && p != NULL){
        i++;
        p = p->next;
    } 
    //p为插入结点的前一个结点,当链表为空时,p就为头结点
    m = (LinkList)malloc(sizeof(Node));
    m->data = data;
    m->frequent = 0;

    m->next = p->next;
    m->pre = p;
	
	//p可能是头结点,即初始状态为该链表为空,p->next为NULL,所以需要进行判断
    if(p->next != NULL){
         p->next->pre = m;
    }
    p->next = m;
    return 1;
}

删除方法

int ListDelete(LinkList *L,int n,int *data){
    int i = 1;
    LinkList p,m;
    p = *L;
    while(i < n && p->next != NULL){
        i++;
        p = p->next;
    }
    //p为删除结点的前一个结点
    m = p->next;
    *data = m->data;

    p->next = m->next;
    //因为删除的结点可能是最后一个结点,所以需要对m的后序进行判断
    if(m->next != NULL){
        m->next->pre = p;
    }
    free(m);
    return 1;
}

查找x的方法

int Locate(LinkList L,int data){
    LinkList p , m;
    p = L->next;
    while(p){
        if(p->data == data){
            p->frequent += 1;
            m = p->pre;
            while(p->pre){
                m = p->pre;
                if(p->frequent <= m->frequent){
                    break;
                }
                p->pre = m->pre;
                m->next = p->next;

                m->pre->next = p;
                if(p->next){
                    p->next->pre = m;
                }

                p->next = m;
                m->pre = p;

            }
            return 1;
        }
        p = p->next;
    }
    printf("not find\n");
    return 0;
}

2.查找互异数列

求出所有的递增和递减的数列的数目,例如数列(7,2,6,9,8,3,5,2,1),可分为(7,2)(2,6,9)(9,8,3)(3,5)(5,2,1),结果是5

int FindHY(LinkList L){
    int count = 0;
    int flag;
    LinkList p,m;
    p = L->next;
    while(p->next){ // 由于要与后面的进行比较,所以只遍历到倒数第2个
    	//flag = 1,递增
    	//flag = 0,递减
        flag = (p->next->data > p->data) ? 1 : 0;
        m = p;
        while(m->next){
            if(flag == 1){ //如果是递增
                if(m->data > m->next->data){ //当发现当前结点比后面的结点的值大,就表示当前结点和后面的形成递减,就结束当前循环,m就为p的值
                    break;
                }
                m = m->next;  //如果依然比后面的大,就继续遍历
            }else{  //如果是递减
                if(m->data < m->next->data){//当发现当前结点比后面的结点的值小,就表示当前结点和后面的形成递增,就结束当前循环,m就为p的值
                    break;
                }
                m = m->next;
            }
        }
        p = m;
        count++;  //递增或者递减数量之和
    }
    printf("count = %d\n",count);
    return 1;
}

3.动态顺序表,交换正负数位次

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 100
#define INIT_SIZE 10  //初始化的长度
typedef struct Node{
    int *head;
    int length;  //当前长度
    int maxSize; //顺序表当前最大容量
}SqList;

int InitList(SqList *L);
int Insert(SqList *L, int data,int n);
int Delete(SqList *L,int *data,int n);
void Traverse(SqList L);
int SwapNumber(SqList L);

int main()
{
    int n ,temp;
    SqList L;
    InitList(&L);
    printf("number = :\n"); 
    scanf("%d",&n);
    srand((unsigned)time(NULL));
    while(n){
        temp = rand()% MAX_SIZE - 49;   //temp [-50,50]
        Insert(&L,temp,1);
        n--;
    }
    Traverse(L);
    SwapNumber(L);
    Traverse(L);
    return 0;
}
int InitList(SqList *L){
   int *p;
   p = (int *)malloc(INIT_SIZE * sizeof(int));
   if(p == NULL){
        printf("initialize error");
        return 0;
   }
   L->head = p;
   L->length = 0;
   L->maxSize = INIT_SIZE;
   return 1;
}
int Insert(SqList *L, int data, int n){
    int *p;
    if(n < 1 || n > L->length + 1){
        printf("insert error");
        return 0;
    }
    if(L->length == L->maxSize){ //如果当前长度已经达到最大值,就扩充
        p = realloc(L->head,(L->length + INIT_SIZE) * sizeof(int));
        if(p == NULL){
            printf("realloc error");
            return 0;
        }
        L->head = p;
        L->maxSize += INIT_SIZE;
    }
    //从顺序表最后1个开始,到插入结点的位置,均往后移动一位
    for(p = L->head + L->length;p > (L->head + n - 1); p--){
        *(p) = *(p - 1);
    }
    *(p) = data;
    L->length++;
    return 1;
}
int Delete(SqList *L,int *data, int n){
    int *p;
    if(n > L->length || n < 1){
        printf("delete error");
        return 0;
    }
    //从删除结点后一个结点到最后一个结点均往前移动一位
    for(p = L->head + n - 1; p < L->head + L->length - 1; p++){
        *p = *(p + 1);
    }
    L->length--;
    return 1;
}
void Traverse(SqList L){
    int *p;
    int i = L.length;
    p = L.head;
    while(i){
        printf("%4d",*p);
        p++;
        i--;
    }
    printf("\n");
}
int SwapNumber(SqList L){
    int left = 0, right = L.length - 1;
    int temp;
    while(left < right){
        while(L.head[left] < 0 && left < right)
            left++;
        while(L.head[right] > 0 && left < right)
            right--;
        if(left < right){
            temp = L.head[left];
            L.head[left] = L.head[right];
            L.head[right] = temp;
        }
    }
    return 1;
}

5.删除一个递增线性表中重复的元素

int DleteRepeat(LinkList *L){
    LinkList p, m;
    p = (*L)->next;
    while(p->next){
        if(p->data == p->next->data){
            m = p->next;
            p->next = m->next;
            free(m);
        }else{
            p = p->next;
        }
    }
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值