zoukankan      html  css  js  c++  java
  • 【数据结构与算法】单链表操作(C++)

      1 #include <stdio.h>
      2 #include <malloc.h>
      3 /*单链表节点定义*/
      4 typedef struct LNode {
      5     int data;            //data中存放节点数据域 
      6     struct LNode *next;   //指向后继节点的指针
      7 }LNode;  //定义单链表节点类型
      8 
      9 /*例2.3开始*/
     10 /*A和B是两个单链表(带表头结点),其中元素递增有序,设计一个算法,将A 和B归并成一个按元素值非递减有序的链表C,C由A和B中的节点组成*/
     11 void mergeLNodeAsc(LNode *A, LNode *B, LNode *&C) {
     12     LNode *p = A->next;//p用来跟踪A的最小值节点  A->next表示A链表的开始节点(头结点的下一个) A递增,所以p指向他表示指向A的最小节点,即用p来跟踪A的最小节点
     13     LNode *q = B->next;//q来跟踪B的最小值节点
     14     LNode *r; //r始终指向C的终端节点
     15     C = A;//用A的头结点来做C的头结点
     16     C->next = NULL;
     17     free(B); //B的头结点无用,则释放掉
     18     r = C;//r指向C 因为此时头结点也是终端节点
     19     while (p!=NULL&&q!=NULL) {//当p和q都不空时,选取p和q所指节点中的较小者插入C的尾部
     20         if (p->data<=q->data) {
     21             printf("p小于q");
     22             r->next=p; //赋值C的节点
     23             p = p->next; //p前移一个
     24             r = r->next; //r前移一个
     25 
     26         }
     27         else {
     28             printf("q小于p");
     29             r->next = q;
     30             q = q->next;
     31             r = r->next;
     32         }
     33 
     34     }
     35     r->next = NULL; //这一个其实可以去掉 因为至少会剩下一个插入到C的尾部
     36     /*将还有剩余节点的链表插入到C的尾部*/
     37     if (p!=NULL) {
     38         r->next = p;
     39     }
     40     if (q != NULL) {
     41         r->next = q;
     42     }
     43 
     44 }
     45 /*例2.3结束*/
     46 
     47 
     48 /*尾插法建立链表C*/
     49 
     50 void createListR(LNode *&C,int a[],int n) {//要改变的变量用引用型
     51     LNode *s, *r;//s用来指向新申请的节点,r始终指向C的终端节点
     52     int i;
     53     C = (LNode *)malloc(sizeof(LNode));//申请C的头结点空间
     54     C->next = NULL;
     55     r = C;//r指向头结点,因为此时头结点就是终端节点
     56     for (i = 0; i < n;++i) {
     57         s = (LNode *)malloc(sizeof(LNode)); //s指向新申请的节点
     58         s->data = a[i]; //用新申请的节点来接收a的一个元素
     59         r->next = s; //用r来接纳新节点
     60         r = r->next; //用r指向终端节点,以便于接纳下一个到来的节点
     61     }
     62     r->next = NULL;//数组a中所有的元素都已经装入链表C中,C的终端节点的指针域为NULL C建立完成
     63 
     64 }
     65 
     66 /*头插法建立链表C*/
     67 void createListF(LNode *&C, int a[], int n) {//要改变的变量用引用型
     68     LNode *s;//s用来指向新申请的节点
     69     int i;
     70     C = (LNode *)malloc(sizeof(LNode));//申请C的头结点空间
     71     C->next = NULL;
     72     for (i = 0; i < n; ++i) {
     73         s = (LNode *)malloc(sizeof(LNode)); //s指向新申请的节点
     74         s->data = a[i]; //用新申请的节点来接收a的一个元素
     75         s->next = C->next;//s所指新节点的指针域next指向C的开始节点
     76         C->next = s;//头结点的指针域next指向s节点,使得s称为新的开始节点
     77     }
     78 
     79 }
     80 
     81 /*归并为递减的单链表*/
     82 
     83 void  mergeLNodeDesc(LNode *A,LNode *B,LNode *&C) {
     84 
     85     LNode *p = A->next;
     86     LNode *q = B->next;
     87     LNode *s;
     88     C = A;
     89     C->next = NULL;
     90     free(B);
     91     while (p!=NULL&&q!=NULL) {
     92         if (p->data<=q->data) {
     93             s = p;
     94             p=p->next;
     95             s->next=C->next;
     96             C->next = s;
     97         }
     98         else {
     99             s = q;
    100             q = q->next;
    101             s->next = C->next;
    102             C->next = s;
    103         }
    104     }
    105     /*必须将剩余元素逐个插入C的头部才能得到最终的递减序列*/
    106 
    107     while (p!=NULL) {
    108         s = p;
    109         p = p -> next;
    110         s ->next = C->next;
    111         C->next = s;
    112     }
    113     while (q != NULL) {
    114         s = q;
    115         q = q->next;
    116         s->next = C->next;
    117         C->next = s;
    118     }
    119 
    120 }
    121 
    122 /*例2.4开始*/
    123 /*查找链表C中是否存在一个值为x的节点,若存在,则删除该节点并返回1,否则返回0*/
    124 
    125 int findAndDelete(LNode *C,int x) {
    126     LNode *p, *q; /*q用来接纳删除的元素 ,p用来指向C的节点*/
    127     p = C;
    128     while (p->next!=NULL) {
    129 
    130         if (p->next->data ==x) {/*查找的是要删除节点的额前驱节点*/
    131             break;
    132         }
    133         p = p->next; /*如果当前不是要找的节点 则p向后移*/
    134     }
    135     /*没找到*/
    136     if (p->next ==NULL) {
    137         return 0;
    138     
    139     }
    140     else {
    141         /*删除部分开始*/
    142         q = p->next;
    143         p->next = p->next->next;
    144         free(q);
    145         /*删除部分结束*/
    146         return 1;
    147     }
    148 
    149 }
    150 /*例2.4结束*/
    151 
    152 /*打印链表中的元素*/
    153 void showLNode(LNode *C) {
    154     LNode *p;
    155     p = C;
    156     while (p->next!=NULL) {
    157         printf("C的数据为:%d
    ", p->next->data);
    158         p = p->next;
    159     }
    160     
    161 }
    162 
    163 void main() {
    164 
    165     LNode *C;
    166     int a[] = { 1,2,3,4 };
    167     int n = 4;
    168     createListF(C, a, n);
    169     showLNode(C);// 4 3 2 1 
    170     findAndDelete(C, 2);
    171     showLNode(C);// 4 3 1
    172 
    173 
    174     LNode *D;
    175     int b[] = { 1,2,3,4,5,6 };
    176     int m = 6;
    177     createListR(D, b, m);
    178     showLNode(D); // 1 2 3 4 5 6
    179 
    180     findAndDelete(D, 8);
    181     showLNode(D);// 1 2 3 4 5 6
    182     printf("开始合并数组");
    183 
    184     LNode *M;
    185     int m1[] = { 1,3,5 };
    186     int m2 = 3;
    187     createListR(M, m1, m2);
    188     LNode *N;
    189     int n1[] = { 2,4,6 };
    190     int n2 = 3;
    191     createListR(N, n1, n2);
    192     LNode *O;
    193     mergeLNodeDesc(M, N,O);
    194     showLNode(O);// 6 5 4 3 2 1
    195 
    196     LNode *Q;
    197     int q1[] = { 1,3,5 };
    198     int q2 = 3;
    199     createListR(Q, q1, q2);
    200     LNode *R;
    201     int r1[] = { 2,4,6 };
    202     int r2 = 3;
    203     createListR(R, r1, r2);
    204     LNode *P;
    205     mergeLNodeAsc(Q, R, P);
    206     showLNode(P);// 1 2 3 4 5 6
    207 }
  • 相关阅读:
    java解析xml的几种方式
    Android Studio 问题解决List
    Android 无线调试方法
    Android 单选/复选控件
    clr
    jquery.metadata.js使用分析
    更改新建Asp.net WebForm的模板 的方法
    获取定位数据
    简易水平仪实现
    简易指南针实现
  • 原文地址:https://www.cnblogs.com/dream-to-pku/p/11426001.html
Copyright © 2011-2022 走看看