c语言双相链表,C语言双向链表

发布时间:2022-11-28

本文目录一览:

  1. C语言、双向链表
  2. C语言双向链表
  3. C语言定义双向链表结构体
  4. 使用C语言实现双向链表的建立、删除和插入
  5. 求问c语言单向链表和双向链表与循环链表的区别

C语言、双向链表

// Node.h 声明类Node
#ifndef Node_H
#define Node_H
template <class T>
class LinkList; // 为是Node类的友员类而声明
template <class T>
class Node {
public:
    friend class LinkList<T>; // 将LinkList类设为友元类
private:
    T data;
    Node<T> *next;
};
#endif
// LinkList.h 声明类LinkList
#ifndef LinkQueue_H
#define LinkQueue_H
#include "Node.h"
template <class T>
class LinkList {
public:
    LinkList(); // 建立只有头结点的空链表
    LinkList(T a[], int n); // 建立有n个元素的单链表
    ~LinkList(); // 析构函数
    int Length(); // 求单链表的长度
    T Get(int i); // 取单链表中第i个结点的元素值
    int Locate(T x); // 求单链表中值为x的元素序号
    void Insert(int i, T x); // 在单链表中第i个位置插入元素值为x的结点
    T Delete(int i); // 在单链表中删除第i个结点
    void PrintList(); // 遍历单链表,按序号依次输出各元素
private:
    Node<T> *first; // 单链表的头指针
};
#endif
// LinkList.cpp
#include "LinkList.h"
/*
 * 前置条件:单链表不存在
 * 输 入:无
 * 功 能:构建一个单链表
 * 输 出:无
 * 后置条件:构建一个单链表
 */
template <class T>
LinkList<T>::LinkList() {
    first = new Node<T>;
    first->next = NULL;
}
/*
 * 前置条件:单链表不存在
 * 输 入:顺序表信息的数组形式a[],单链表长度n
 * 功 能:将数组a[]中元素建为长度为n的单链表
 * 输 出:无
 * 后置条件:构建一个单链表
 */
template <class T>
LinkList<T>::LinkList(T a[], int n) {
    first = new Node<T>; // 生成头结点
    Node<T> *r, *s;
    r = first; // 尾指针初始化
    for (int i = 0; i < n; i++) {
        s = new Node<T>;
        s->data = a[i]; // 为每个数组元素建立一个结点
        r->next = s;
        r = s; // 插入到终端结点之后
    }
    r->next = NULL; // 单链表建立完毕,将终端结点的指针域置空
}
/*
 * 前置条件:无
 * 输 入:无
 * 功 能:无
 * 输 出:无
 * 后置条件:无
 */
template <class T>
LinkList<T>::~LinkList() {
}
/*
 * 前置条件:单链表存在
 * 输 入:查询元素位置i
 * 功 能:按位查找位置为i的元素并输出值
 * 输 出:查询元素的值
 * 后置条件:单链表不变
 */
template <class T>
T LinkList<T>::Get(int i) {
    Node<T> *p;
    int j;
    p = first->next;
    j = 1; // 或p=first; j=0;
    while (p && j < i) {
        p = p->next; // 工作指针p后移
        j++;
    }
    if (!p)
        throw "位置";
    else
        return p->data;
}
/*
 * 前置条件:单链表存在
 * 输 入:查询元素值x
 * 功 能:按值查找值的元素并输出位置
 * 输 出:查询元素的位置
 * 后置条件:单链表不变
 */
template <class T>
int LinkList<T>::Locate(T x) {
    Node<T> *p;
    int j;
    p = first->next;
    j = 1;
    if (p && p->next) {
        while (p->data != x) {
            p = p->next;
            j++;
        }
        return j;
    } else
        throw "位置";
}
/*
 * 前置条件:单链表存在
 * 输 入:插入元素x,插入位置i
 * 功 能:将元素x插入到单链表中位置i处
 * 输 出:无
 * 后置条件:单链表插入新元素
 */
template <class T>
void LinkList<T>::Insert(int i, T x) {
    Node<T> *p;
    int j;
    p = first;
    j = 0; // 工作指针p初始化
    while (p && j < i - 1) {
        p = p->next; // 工作指针p后移
        j++;
    }
    if (!p)
        throw "位置";
    else {
        Node<T> *s;
        s = new Node<T>;
        s->data = x; // 向内存申请一个结点s,其数据域为x
        s->next = p->next; // 将结点s插入到结点p之后
        p->next = s;
    }
}
/*
 * 前置条件:单链表存在
 * 输 入:无
 * 功 能:输出单链表长度
 * 输 出:单链表长度
 * 后置条件:单链表不变
 */
template <class T>
int LinkList<T>::Length() {
    Node<T> *p = first->next;
    int i = 0;
    while (p) {
        p = p->next;
        i++;
    }
    return i;
}
/*
 * 前置条件:单链表存在
 * 输 入:要删除元素位置i
 * 功 能:删除单链表中位置为i的元素
 * 输 出:无
 * 后置条件:单链表删除元素
 */
template <class T>
T LinkList<T>::Delete(int i) {
    Node<T> *p;
    int j;
    p = first;
    j = 0; // 工作指针p初始化
    while (p && j < i - 1) { // 查找第i-1个结点
        p = p->next;
        j++;
    }
    if (!p || !p->next)
        throw "位置"; // 结点p不存在或结点p的后继结点不存在
    else {
        Node<T> *q;
        int x;
        q = p->next;
        x = q->data; // 暂存被删结点
        p->next = q->next; // 摘链
        delete q;
        return x;
    }
}
/*
 * 前置条件:单链表存在
 * 输 入:无
 * 功 能:单链表遍历
 * 输 出:输出所有元素
 * 后置条件:单链表不变
 */
template <class T>
void LinkList<T>::PrintList() {
    Node<T> *p;
    p = first->next;
    while (p) {
        cout << p->data << endl;
        p = p->next;
    }
}
#include <iostream.h>
#include "LinkList.cpp"
#include "Node.h"
void main() {
    LinkList<int> a;
    cout << "执行插入操作:" << endl;
    try {
        a.Insert(1, 4);
        a.Insert(2, 5);
        a.Insert(3, 6);
    } catch (char *wrong) {
        cout << wrong; // 如失败提示失败信息
    }
    cout << "已经插入“4,5,6”" << endl;
    cout << "单链表a的长度为:" << endl;
    cout << a.Length() << endl; // 返回单链表长度
    cout << endl;
    cout << "单链表a的元素为:" << endl;
    a.PrintList(); // 显示链表中所有元素
    cout << endl;
    cout << "按位查找第二个元素:" << endl;
    cout << "第二个元素为:";
    cout << a.Get(2) << endl; // 查找链表中第二个元素
    cout << endl;
    cout << "按值查找5" << endl;
    cout << "值为5的元素位置为:";
    cout << a.Locate(5) << endl; // 查找元素5,并返回在单链表中位置
    cout << endl;
    cout << "执行删除4的操作" << endl;
    a.Delete(1); // 删除元素4
    cout << "已删除成功,单链表a的长度为";
    cout << a.Length() << endl;
    cout << endl;
    cout << "链表a中的元素为:" << endl;
    a.PrintList();
    int r[] = {1, 2, 3, 4, 5};
    LinkList<int> b(r, 5); // 根据数组创建顺序表
    cout << "执行插入操作前单链表b为:" << endl;
    b.PrintList(); // 输出单链表所有元素
    cout << "插入前单链表b的长度为:";
    cout << b.Length() << endl;
    try {
        b.Insert(3, 8);
    } catch (char *wrong) {
        cout << wrong; // 如失败提示失败信息
    }
    cout << "执行插入操作后单链表b为:" << endl;
    b.PrintList(); // 输出单链表b所有元素
    cout << "插入后单链表b的长度为:";
    cout << b.Length() << endl;
    cout << endl;
    try {
        if (a.Length()) {
            cout << "执行删除第一个元素操作:" << endl;
            cout << endl;
            b.Delete(1); // 删除b中第一个元素
            cout << "已删除成功,单链表b的长度为:";
            cout << b.Length() << endl;
        } else {
            cout << "顺序表b长度为0" << endl;
        }
    } catch (char *wrong) {
        cout << wrong; // 如失败提示失败信息
    }
    cout << "执行插入操作后单链表b为:" << endl;
    b.PrintList(); // 输出单链表所有元素
}

C语言双向链表

#include "stdio.h"
#include "stdlib.h"
typedef int ElemType; // 元素类型
typedef struct DuLNode {
    // 双向链表
    ElemType data;
    struct DuLNode *prior, *next;
} DuLNode, *DuLinkList;
int Create(DuLinkList L) {
    // 建立双向链表
    DuLinkList p, q;
    ElemType n, i;
    L = (DuLinkList)malloc(sizeof(DuLNode));
    L->next = NULL;
    q = L;
    printf("输入数据个数:");
    scanf("%d", &n);
    printf("输入数据元素:");
    for (i = 0; i < n; i++) {
        p = (DuLinkList)malloc(sizeof(DuLNode));
        scanf("%d", &p->data); // 插入数据
        p->prior = q;
        q->next = p;
        p->next = 0;
        q = q->next;
    }
    return 1;
}
int Visit(DuLinkList L) {
    // 遍历双向链表
    DuLinkList p;
    p = L->next;
    printf("双向链表为:");
    while (p) {
        printf("%4d", p->data);
        p = p->next;
    }
    printf("\n");
    return 1;
}
int Clear(DuLinkList L) {
    DuLinkList p;
    p = L->next;
    while (p) {
        L->next = p->next;
        free(p);
        p = L->next;
    }
    return 1;
}
main() {
    int i, e, s, num;
    char c = 'y';
    DuLinkList L;
    Create(L);
    Visit(L);
    while (c == 'y') {
        printf("\n\n\n1.双向链表插入元素\n2.双向链表中删除元素\n");
        printf("3.判断双向链表元素是否对称\n");
        printf("4.双向链表中奇数排在偶数前面\n");
        printf("5.建立递增链表并有序插入元素\n\n");
        printf("选择需要的操作\n\n");
        scanf("%d", &num);
        switch (num) {
            case 1:
                printf("输入插入元素位置以及元素:\n");
                scanf("%d%d", &i, &e);
                ListInsert(L, i, e);
                Visit(L);
                break;
            case 2:
                printf("输入删除元素位置:");
                scanf("%d", &i);
                Delete(L, i, s);
                printf("删除的元素为:%d\n", s);
                Visit(L);
                break;
            case 3:
                if (Same(L))
                    printf("链表对称\n");
                else
                    printf("链表不对称\n");
                break;
            case 5:
                printf("清空原链表,建立递增链表:\n");
                XCreate(L);
                Visit(L);
                break;
            case 4:
                printf("奇数放在偶数前面:\n");
                Jiou(L);
                Visit(L);
                break;
        }
        printf("继续操作(y/n):\n");
        scanf("%s", &c);
    }
}

C语言定义双向链表结构体

struct node {
    DataType data;
    struct node *prior;
    struct node *next;
};

其中 prior 指针用来存储前一节点的地址,next 用来存储后一节点的地址,就比单项链表多了一个指针而已,可以添加其它自定义的数据成员。

使用C语言实现双向链表的建立、删除和插入

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct list {
    int data;
    struct list *next;
    struct list *pre;
};
typedef struct list node;
typedef node *link;
link front = NULL, rear, ptr, head = NULL;
link push(int item) {
    link newnode = (link)malloc(sizeof(node));
    newnode->data = item;
    if (head == NULL) {
        head = newnode;
        head->next = NULL;
        head->pre = NULL;
        rear = head;
    } else {
        rear->next = newnode;
        newnode->pre = rear;
        newnode->next = NULL;
        rear = newnode;
    }
    return head;
}
void makenull() {
    front = NULL;
    rear = NULL;
}
empty() {
    if (front == NULL)
        return 1;
    else
        return 0;
}
int tops() {
    if (empty())
        return NULL;
    else
        return rear->data;
}
void pop() {
    if (empty())
        printf("stack is empty!\n");
    else
        rear = rear->pre;
}
void display(link l) {
    link p;
    p = l;
    while (p != NULL) {
        printf("%d-", p->data);
        p = p->next;
    }
}
void main() {
    int n, i;
    printf("input your first data!\n");
    scanf("%d", &n);
    front = push(n);
    /* another data */
    for (i = 0; i < 3; i++) {
        printf("input:\n");
        scanf("%d", &n);
        push(n);
    }
    ptr = front;
    display(ptr);
    printf("\n Please enter any key to pop");
    pop();
    ptr = front;
    display(ptr);
}

求问c语言单向链表和双向链表与循环链表的区别

打个比方。把链表节点看作是一个人,把链表指针看作是人的手(左手是前向指针,右手是后向指针)。 非循环的单向链表 是这样的:若干个人排成一排,每个人都抬起右手指向他右边的人,最右边的人的右手指向了空气(NULL)。如果要想找到这一排中任意一个人,必须从排头(链表头)开始沿手指的方向挨个查找。 循环单向链表 是这样的:若干个人围成一圈,每个人都抬起右手指向他右边的人,这样每个人的右手都能指到一个人(如果只有一个人,那么他的右手指向自己)。从任意一个人开始,沿着手指的方向,可以不停地循环找到每一个人。 非循环的双向链表 是这样的:若干个人排成一排,每个人都抬起左手指向他左边的人,并且每个人都抬起右手指向他右边的人,那么最左边的人的左手指向了空气(NULL),最右边的人的右手指向了空气(NULL)。如果要想找到这一排中某个目标人,从任意一个人开始,可以沿左手方向尝试查找,如果找不到,可以继续沿右手方向查找,直到找到目标人。 循环双向链表 是这样的:若干个人围成一圈,每个人都抬起左手指向他左边的人,并且每个人都抬起右手指向他右边的人,这样每个人的左右手都可以指到一个人(如果只有一个人,那么他的左右手都指向自己)。无论选择左手方向还是右手方向,都可以不停地循环找到每一个人。