List

作者: jmychou | 来源:发表于2016-11-02 22:45 被阅读11次
  1. c# List<int> 转 string 以及 s
  2. php redis list
  3. 【Python爬虫】- 第4天列表、元组、集合练习题
  4. Python学习笔记(四)
  5. Android 比较两个集合中的不同元素
  6. JAVA中list的应用+理解
  7. 列表
  8. Python list总结
  9. new为指针
  10. List、 List、 List三者的区别

    include<iostream>

    using namespace std;

    //单链表

    typedef struct Lnode{

    int data;

    struct Lnode *next;

    }Lnode;

    //双链表

    typedef struct DLnode{

    int data;

    struct DLnode *next;

    }DLnode;

    /*

    尾插法建立单链表

    */

    Lnode * Create(Lnode *head, int *a, int n){

    Lnode *first, *node;

    first = (Lnode *)malloc(sizeof(Lnode)); //头结点

    head = first;

    first->next = NULL;

    for (int i = 0; i < n; ++i){

    node = (Lnode *)malloc(sizeof(Lnode));

    node->data = *(a + i);

    first->next = node;

    first = first->next;

    }

    first->next = NULL;

    return head;

    }

    /*

    头插法建立单链表

    */

    Lnode * HeadCreate(Lnode *head, int *a, int n){

    Lnode *first, *node;

    first = (Lnode *)malloc(sizeof(Lnode)); //头结点

    head = first;

    first->next = NULL;

    for (int i = 0; i < n; ++i){

    node = (Lnode *)malloc(sizeof(Lnode));

    node->data = *(a + i);

    node->next = first->next;

    first->next = node;

    }

    return head;

    }

    /*

    在指定位置插入节点val

    */

    Lnode * Insert(Lnode * head, int n, int val){

    Lnode *p = head;

    Lnode node = (Lnode)malloc(sizeof(Lnode));

    for (int i = 0; i < n - 1; ++i){

    p = p->next;

    }

    node->data = val;

    node->next = p->next;

    p->next = node;

    return head;

    }

    /*

    删除 data 为val的某个节点

    */

    int Del(Lnode *head, int val){

    Lnode*p, *q;

    p = head; //传入头指针,然后p保存头指针信息,修改p,即等同于修改head头指针

    while (p->next != NULL){ //p指向删除节点的前一个节点

    if (p->next->data == val)

    {

    break;

    }

    p = p->next;

    }

    if (p->next == NULL){

    return 0;

    }

    else{

    q = p->next;

    p->next = q->next;

    free(q);

    return 1;

    }

    }

    /*

    单链表反转

    */

    Lnode* Reverse(Lnode *head){

    Lnode *first = head->next, *tmp;

    head->next = NULL;

    while (first != NULL)

    {

    tmp = first->next;

    first->next = head->next;

    head->next = first;

    first = tmp;

    }

    return head;

    }

    /*

    • 构建有环单链表

    */

    Lnode *CirLnode(Lnode *head, int num) {

    Lnode *tmp, *tail;

    tmp = tail = head->next;

    for (int i = 1; i < num; ++i) {

    tmp = tmp->next;

    }

    while (tail->next != NULL) {

    tail = tail->next;

    }

    tail->next = tmp;

    return head;

    }

    /*

    • 判断单链表是否有环

    */

    int IsCir(Lnode *head) {

    Lnode *first, *last;

    first = head;

    last = head;

    while (last != NULL && last->next != NULL) {

    last = last->next->next;

    first = first->next;

    if (first == last) {

    cout << first->data << endl; //在环中相遇的点,不一定是环的初始点

    //求环的初始点

    first = head;

    while (first->next!=NULL){ //first和last在环中相遇的时候,使first指针回到head节点,last不动,然后first和last都每次走一步,两者再次相遇的点就是环的初始节点

    first = first->next;

    last = last->next;

    if (first == last){

    cout << "初始环点" << first->data << endl;

    break;

    }

    }

    return 1;

    }

    }

    return 0;

    }

    /*

    约瑟夫环问题

    */

    int JoseCircle(Lnode *head,int num){

    Lnode p = head,tmp,*q;

    int i = 1;

    q = p->next;

    while (p!=q){

    i++;

    p = q;

    q = q->next;

    if (i == num){

    tmp = q;

    p->next = tmp->next;

    q = p->next;

    free(tmp);

    i = 1;

    }

    }

    return q->data;

    }

    /*

    查找单链表中的倒数第K个结点(k > 0)

    */

    int FindLast(Lnode * head, int k){

    Lnode *p, *q;

    q = head;

    p = q->next;

    for (int i = 0; i < k; ++i){ //使用两个指针,前面的指针走到正K,后面的指向第一个,两者相差为k-1,然后同时走,直到前面走到最后,后指针的位置即为所求

    q = q->next;

    }

    if (q == NULL){ //k大于链表个数

    return -1;

    }

    while (q->next != NULL){

    p = p->next;

    q = q->next;

    }

    /*

    while(p){

    p=p->next;

    i++;

    if(i>k) q=q->next; //p先走,只有存在p走过了K个节点,q才开始走,当p走到终点,q指向倒数K个节点

    }

    if(q==head) return 0; //q要么指向头结点,要么指向倒数第K个

    else cout<<q->data<<endl;

    */

    return p->data;

    }

    /*

    • 删除相同节点

    */

    Lnode *DelSame(Lnode *head) {

    Lnode *p, *q, *tmp;

    p = head->next;

    while (p != NULL) {

    q = p;

    while (q->next != NULL) {

    if (q->next->data == p->data) {

    tmp = q->next;

    q->next = tmp->next;

    free(tmp);

    }

    else{

    q = q->next;

    }

    }

    p = p->next;

    }

    return head;

    }

    /*

    查找单链表的中间节点

    */

    int FindMid(Lnode *head){

    Lnode *p, *q;

    p = q = head->next;

    while (q->next != NULL){

    if (q->next->next != NULL){

    p = p->next;

    q = q->next->next;

    }

    else{

    break;

    }

    }

    return p->data;

    }

    /*

    统计节点的个数

    */

    int CalcNum(Lnode *head){

    int n = 0;

    Lnode *tmp = head;

    if (head->next == NULL){

    return n;

    }

    else{

    while (tmp->next != NULL){

    n++;

    tmp = tmp->next;

    }

    return n;

    }

    }

    /*

    • 合并两个有序链表

    */

    Lnode *MergeLnode(Lnode *h1, Lnode *h2) {

    Lnode *p1, *p2, *p3, *q;

    p1 = h1->next, p2 = h2->next;

    q = p3 = h1;

    q->next = NULL;

    while (p1 != NULL && p2 != NULL) {

    if (p1->data <= p2->data) {

    q->next = p1;

    p1 = p1->next;

    }

    else {

    q->next = p2;

    p2 = p2->next;

    }

    q = q->next;

    }

    if (p1 != NULL) q->next = p1;

    if (p2 != NULL) q->next = p2;

    return p3;

    }

    /*

    • 求A,B链表的差集A-B

    */

    Lnode *Diff(Lnode *h1, Lnode *h2) {

    Lnode *p = h1, *q = h2;

    Lnode *tmp;

    while (p->next != NULL && q->next != NULL) {

    if (p->next->data < q->next->data) {

    p = p->next;

    }

    else if (p->next->data > q->next->data) {

    q = q->next;

    }

    else {

    tmp = p->next;

    p->next = tmp->next;

    free(tmp);

    }

    }

    return h1;

    }

    /*

    求A,B链表的交集

    */

    void Common(Lnode *h1, Lnode *h2){

    Lnode *p = h1, *q = h2;

    while (p->next != NULL && q->next != NULL) {

    if (p->next->data < q->next->data) {

    p = p->next;

    }

    else if (p->next->data > q->next->data) {

    q = q->next;

    }

    else {

    cout << p->next->data << " ";

    p = p->next;

    q = q->next;

    }

    }

    cout << endl;

    }

    /*

    删除单链表中的最小值节点

    */

    Lnode *DelMin(Lnode *head){

    Lnode *q = head->next, min = q,tmp=head;

    while (q != NULL && q->next!=NULL){

    if (q->next->data < min->data){

    tmp = q;

    min = q->next;

    }

    q = q->next;

    }

    tmp->next = min->next;

    free(min);

    return head;

    }

    /*

    将A链表拆分成A,B,其中A是data为奇数的点,B是data为偶数的点,顺序不变

    */

    Lnode * SplitLink(Lnode *h1, Lnode *h2){

    Lnode p = h1,t ;

    Lnode *q = (Lnode *)malloc(sizeof(Lnode));

    h2 = q;

    q->next = NULL;

    while (p->next != NULL){

    if (p->next->data % 2 == 0){ //如果是偶数,就取出 放到B中,否则就继续前进,然后A就剩余奇数

    t = p->next;

    p->next = t->next;

    t->next = NULL;

    q->next = t;

    q = q->next;

    }

    else{

    p = p->next;

    }

    }

    return h2;

    }

    /*

    按照val值将单链表分成左右部分,左边比它小,右边比它大

    */

    Lnode * Partation(Lnode *head,int val){

    Lnode *p = head;

    Lnode *small, *equal, *big; //将单链表拆成三个链表, 分别定义三个头指针,

    small = equal = big = NULL;

    Lnode * smallA, *equalA, *bigA ; //三个链表的尾指针

    smallA = equalA = bigA = NULL;

    while (p->next!=NULL){

    if (p->next->data < val){

    if (small == NULL){ //初始时,头尾指针均指向第一个进入大,等,小的节点

    smallA = small = p->next;

    }

    else{

    smallA->next = p->next; //不是第一个节点的时候,采用尾插法将节点插入链表

    smallA = smallA->next;

    }

    }

    else if (p->next->data == val){

    if (equal == NULL){

    equalA = equal = p->next;

    }

    else{

    equalA->next = p->next;

    equalA = equalA->next;

    }

    }

    else {

    if (big == NULL){

    bigA = big = p->next;

    }

    else{

    bigA->next = p->next;

    bigA = bigA->next;

    }

    }

    p = p->next;

    }

    if (small!=NULL && equalA != NULL) { //当小链表不为空,且等链表不为空,链接两个链表,等链表后置为空

    equalA->next = NULL;

    smallA->next = equal;

    }

    if (equalA!=NULL && bigA != NULL) { // 同理链接等链表和大链表

    bigA->next = NULL;

    equalA->next = big;

    }

    head->next = small != NULL ? small : equal != NULL ? equal : big;

    return head;

    }

    /*

    正序打印单链表

    */

    void show(Lnode * head){

    while (head->next != NULL){

    cout << head->next->data << " ";

    head = head->next;

    }

    cout << endl;

    }

    /*

    逆序打印单链表

    */

    void ShowTail(Lnode *head) { //print from tail,颠倒顺序的问题,采用栈,并且去掉头结点

    Lnode *p = head;

    if (p == NULL) {

    return;

    }

    ShowTail(p->next);

    cout << p->data << " ";

    }

    void tt(int *p){

    int a = 3;

    int *q = p;

    q = &a;

    }

    void test(Lnode *head){ //一个单链表,first指针在前,last指针在后,first置空后,last便访问不到first后的节点

    //last置空后,并不妨碍first访问后面的节点

    Lnode *p = head->next;

    Lnode *q = p;

    p = p->next->next;

    p->next = NULL;

    q = q->next;

    cout << p->data << endl;

    }

    void main(){

    int a[] = {2,1,3,5,4};

    int b[] = { 3,4, 5, 6, 7, 8 };

    int lenA = sizeof(a) / sizeof(a[0]);

    int lenB = sizeof(b) / sizeof(b[0]);

    Lnode *head = NULL, *tail = NULL , *h2=NULL; //头指针

    head = Create(head, a, lenA); //指针作为函数参数时,传递的也是指针的地址拷贝,所以指正不会改变,传入堆指针时,指针的值才会变化

    show(head);

    tail = HeadCreate(tail, b, lenB);

    Reverse(tail);

    show(tail);

    /*

    cout << "节点个数为: " << CalcNum(head) << endl;

    *tail = Reverse(tail);

    show(tail);

    if (Del(head, 4) > 0){

    cout << "找到并删除" << endl;

    show(head);

    }

    Insert(head, 3, 6);

    show(head);

    cout << "节点个数为: " << CalcNum(head) << endl;

    cout << FindMid(head) << endl;

    head = DelMin(head);

    show(head);

    h2=SplitLink(head, h2);

    show(head);

    show(h2);

    int *p = (int *)malloc(sizeof(int));

    tt(p);

    if (p == NULL){

    cout << "null" << endl;

    }

    else{

    cout << " not null" << endl;

    }

    */

    //head = CirLnode(head, 1);

    /*if (IsCir(head)){

    cout << "has a circle " << endl;

    }

    else{

    cout << "no circle " << endl;

    }*/

    //cout << "Last out " << JoseCircle(head, 3) << endl;

    //Common(head, tail);

    head = Partation(head, 2);

    show(head);

    free(head);

    free(tail);

    system("pause");

    }

    相关文章