数据结构 非循环单链表(C语言)

二刷链表,纪念一下。
代码实现了以下的功能:

  1. 链表的创建。
  2. 链表的输出。
  3. 判断链表是否为空。
  4. 插入结点。
  5. 删除结点。
  6. 计算链表的长度。
  7. 排序。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>

typedef struct Node
{
    int date;//数据域
    struct Node * next;//指针域
}NODE;

NODE * creatList()
{
    int len;
    int i;
    int value;

    NODE * head = (NODE * )malloc(sizeof(NODE));//创建头结点,head存放其地址。
    if(NULL == head)
    {
        printf("内存分配失败,程序终止!\n");
        exit(-1);
    }

    NODE * tail = head;//定义尾指针,一直指向最后一个结点。
    tail->next = NULL;

    printf("请输入您需要生成的链表结点的个数:len = ");
    scanf("%d", &len);

    for(i = 1; i <= len; i++)
    {
        printf("请输入第%d个结点的值:\n", i);
        scanf("%d", &value);

        NODE * p = (NODE * )malloc(sizeof(NODE));
        if(NULL == p)
        {
            printf("内存分配失败,程序终止!\n");
            exit(-1);
        }

        p->date = value;//给新创建的链表数据域赋值。

        tail->next = p;
        p->next = NULL;
        tail = p;
    }

    return head;
}

void traverseList(NODE * head)
{
    NODE * p = head->next;

    while(p != NULL)
    {
        printf("%5d",p->date);
        p = p->next;
    }
    printf("\n");

    return;
}

bool is_empty(NODE * head)
{
    if(head->next == NULL)
        return true;
    else
        return false;
}

bool insert(NODE * head, int position, int value)
//在第positi个结点的前面插入一个新的结点,新的结点的数据域为value。
{
    int i = 0;
    NODE * p = head;

    while(NULL != p && i<position-1)
    {
        p = p->next;
        i++;
    }
    if(i>position-1 || NULL == p)
        return false;
    //此时p指向第position个结点。

    NODE * pVal = (NODE * )malloc(sizeof(NODE));
    if(NULL == pVal)
    {
        printf("动态分配内存失败!\n");
        exit(-1);
    }
    pVal->date = value;
    //分配内存,pVal指向新的结点,把value赋值给新的结点的数据域。

    NODE * p1 = p->next;//p此时指向第position-1个结点。p1指向第positon个结点。
    p->next = pVal;//把新的结点挂在第position-1个结点后面。
    pVal->next = p1;//原先链表的第positon个结点挂在新的链表后面。

    return true;
}

bool delete(NODE * head, int position, int * pVal)
//删除第position个结点,并把此结点的数据域的值赋值给main函数中的int类型的变量。
{
    int i = 0;
    NODE * p = head;

    while(NULL != p->next && i<position-1)
    {
        p = p->next;
        i++;
    }
    if(i>position-1 || NULL == p->next)
        return false;

    NODE * p1 = p->next;//p1指向要删除的结点。
    * pVal = p1->date;//把要删除的结点的值赋值给* pVal。

    p->next = p->next->next;

    free(p1);
    p1 = NULL;

    return true;
}

int length(NODE * head)
{
    int len = 0;
    NODE * p = head->next;

    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    return len;
}

void sort(NODE * head)
{
    int i, j, t;
    int len = length(head);
    NODE * p, * q;

    for(i = 0, p = head->next; i < len-1; i++, p = p->next)
        for(j = i+1,q = p->next; j<len; j++, q = q->next)
        {
            if(p->date>q->date)
            {
                t = p->date;
                p->date = q->date;
                q->date = t;
            }
        }

    return;
}

int main(void)
{
    NODE * head = NULL;
    int val;

    head = creatList();//创建一个非循环单链表。

    if(is_empty(head))//判断链表是否为空。
        printf("链表为空!\n");
    else
        printf("链表不为空!\n");

    printf("创建链表成功后,链表输出:\n");
    traverseList(head);//遍历链表。

    printf("排序后,链表输出:\n");
    sort(head);

    traverseList(head);

    printf("链表长度为%d\n",length(head));//输出链表的长度。


    insert(head,  4, 33);//把33插入到第三和第四个结点之间。

    printf("插入成功后,链表输出:\n");
    traverseList(head);

    printf("\n");


    if(delete(head, 4, &val))//删除第四个结点,并把其数据域的值赋给val。
        printf("删除成功,您删除的元素是:%d\n",val);
    else
        printf("删除失败,您删除的元素不存在!\n");

//    printf("删除成功后,链表输出:\n");
//    traverseList(head);

    return 0;
}

代码运行后。
在这里插入图片描述

#include<iostream> using namespace std; enum yaya { error,success }; struct node { int data; node*next; }; class List{ public: List(); ~List(); int length(); yaya set_data(int n); node* get_ptr(int m); yaya inset_node(int x,int y); int delete_node(int i); void put_in(int x); void breaktwo(List&la,List&lb); void same_data(List&l1,List&l2,List&l); int out_data(); private: int count; node* head; }; List::List(){ head=new node; head->next=NULL; count=0; } int List::length(){ return count; } yaya List::set_data(int n){ node*p=head; for(int j=0;j<n;j++){ cin>>p->data; p=p->next; count++; if(p==NULL){ return error; } } return success; } node* List::get_ptr(int m){ node*p=head; int j=0; while(p!=NULL&&j<m){ j++; p=p->next; } return p; } yaya List::inset_node(int x,int y){ if(x<=0||x>count+1){ return error; } node*p=new node; p->data=y; node*current=head; for(int j=1;j<x;j++){ current=current->next; } p->next=current->next; current->next=p; count++; return success; } int List::delete_node(int i){ if(i<=0||i>count) return NULL; node*current=head; for(int j=1;j<i;j++){ current=current->next; }node*u=current->next; current->next=u->next; delete u; count--; return success; } void List::put_in(int x){ node*p=new node; p->data=x; node*current=head; for(;current!=NULL&&current->next!=NULL&&current->next->data<x;){ current=current->next; } p->next=current->next; current->next=p; count++; return; } void List::breaktwo(List& la,List& lb){ node*q=head->next; la.inset_node(la.count+1,q->data); while(q!=NULL&&q->next!=NULL&&q->next->next!=NULL){ q=q->next->next; la.inset_node(la.count+1,q->data); } node*w=head->next->next; lb.inset_node(lb.count+1,w->data); while(w!=NULL&&w->next!=NULL&&w->next->next!=NULL){ w=w->next->next; lb.inset_node(lb.count+1,w->data); } } void List::same_data(List&l1,List&l2,List&l){ node*p=l1.head; for(int i=1;i<=l1.count;i++){ p=p->next; node*q=l2.head; for(int j=1;j<=l2.count;j++){ q=q->next; if(p->data==q->data) l.inset_node(l.length()+1,p->data); } } } int List::out_data(){ node*p=head; for(int j=1;j<=count;j++){ p=p->next; cout<<(p->data)<<" "; } cout<<endl; return 0; } List::~List(){ node*p=head,*s; while(p!=NULL){ s=p; p=p->next; delete s; } }
循环单链表是链表的一种特殊形式,它的特点是链表中的最后一个节点的指针指向第一个节点,形成一个闭合的环。在C语言中,操作循环单链表通常涉及创建、插入、删除和遍历等基本操作。 以下是一些基本操作的C语言实现概览: 1. **创建循环链表**: - 定义节点结构体,包含数据域和指向下一个节点的指针(如果是在头结点的最后一个节点,指针会指向自身)。 - 创建链表时,可以初始化一个头节点,然后递归地添加新节点到链尾。 ```c struct Node { int data; struct Node* next; }; // 创建循环链表 void createCircularList(struct Node** head, int size, ...) { ... } ``` 2. **插入节点**: - 可以在链表的头部、尾部或指定位置插入节点。 - 在头部插入,更新头节点的next;在尾部插入,找到当前尾节点,然后更新其next指向新节点,并将新节点next指向头节点。 ```c void insertNode(struct Node** head, int data, insertionPosition) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = (insertionPosition == 1) ? head : (*(head)->next); // 如果在尾部插入,更新尾节点和头节点的next指针 if (insertionPosition == 0) { (*head)->next = newNode; } } ``` 3. **删除节点**: - 删除某个节点时,需要找到前一个节点,然后更新其next指针跳过要删除的节点。 - 在循环链表中删除特定位置的节点需要特别处理头节点的情况。 ```c void deleteNode(struct Node** head, int position) { if (position == 1) { // 删除头节点 struct Node* temp = head->next; *head = temp; free(head); } else { struct Node* current = *head, *previous = NULL; for (int i = 1; i < position && current != NULL; ++i) { previous = current; current = current->next; } if (current == NULL) return; // 未找到节点 previous->next = current->next; } } ``` 4. **遍历循环链表**: - 使用while循环,每次迭代都更新当前节点指向下一个节点,直到遇到第一个节点。 ```c void printList(struct Node* head) { struct Node* temp = head; do { printf("%d ", temp->data); temp = temp->next; } while (temp != head); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值