C语言学习笔记(十三) -链表 Chain

动态申请链表

/*
 动态申请链表

 数组:静态存储,有序的数据集合,数据顺序能够映射物理地址,查找快,插入删除效率低
 链表:动态存储,插入删除效率高
 */

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
    int i;         //保存节点的值,数值域
    struct node *p;//记录下一个节点的地址 ,指针域

} Node;

Node * createlink();
void printLink(Node *head);
void freeLink(Node **phead);
/*
 *Node* 链表首地址
 *int pos 插入新节点的位置
 *int num 新节点的值域
 *返回值: Node* 将新链表的首地址返回
 */
Node *insert(Node* ,int pos,int num);
/*
 *参数:
 *   Node** 指向链表首地址的指针变量的地址
 *   int num 要删除的值,若num和链表中的某个节点的值域相等,则删除该节点
 */
void removeNode(Node **,int num);
Node * insertAsc(Node *head,int num);
Node *createlinkSort();
int main(void)
{
    Node *head=createlink();
    //Node *head=createlinkSort();
    //按顺序打印所有链表内容
    printLink(head);

    printf("插入后的结果为:\n");
    head=insertAsc(head,5);

    //head=insert(head,8,100);
    //printf("remove:\n");
    //removeNode(&head,4);

    printLink(head);
    //freeLink(&head);
    printf("head= %p\n",head);
    //printf("node->i:%d",head->i);
    return 0;
}



//作业
Node * insertAsc(Node *head,int num)
{
    Node *new=(Node *)malloc(sizeof(Node));
    new->i=num;
    new->p=NULL;

    if (head==NULL||head->i> new->i) {   //头结点插入
        new->p=head;
        head=new;
        return head;
    }
    Node *pf,*pb;//pf是要插入的前节点,pb是要插入位置的后节点
    pf=pb=head;
    while (pb!=NULL && pb->i<new->i) {
        pf=pb;
        pb=pb->p;
    }
    if (pb==NULL) {  //尾节点插入
        pf->p=new;
    }else{
        new->p=pb;
        pf->p=new;
    }
    return head;
}
//删除节点
void removeNode(Node **phead,int num)
{
    Node *p1=*phead;
    Node *pf=*phead;
    while (pf!=NULL &&pf->i!=num) {
        p1=pf;
        pf=pf->p;
    }
    if (pf==NULL) {
        printf("链表中没有%d\n",num);
        return ;
    }
    if (pf==*phead) {
        //头节点删除
        *phead=pf->p;
    }else{
        //中间节点和尾节点的删除
        p1->p=pf->p;
    }
    free(pf);

}


//插入节点
Node *insert (Node *head,int pos,int num)
{

    if (pos==0) {   //头结点插入
        Node *newnode=(Node *)malloc(sizeof(Node));
        if (newnode==NULL){
            return head;
        }
        newnode->i=num;
        newnode->p=head;
        head=newnode;
        return head;
    }

    int i=1;
    Node *pf=head;
    while (i<pos && pf!=NULL) {
        pf=pf->p;
        i++;
    }
    if (pf==NULL) {
        printf("链表不能在%d位置中插入节点\n",pos);
    }else{
        Node *newnode=(Node *)malloc(sizeof(Node));
        if (newnode==NULL){
            return head;
        }
        newnode->i=num;
        newnode->p=NULL;

        if (pf->p==NULL) {  //尾节点插入
            pf->p=newnode;
        }else{     //中间节点插入
            newnode->p=pf->p;
            pf->p=newnode;
        }
    }
    return head;
}

//释放链表
void freeLink(Node **phead)
{
    Node *pf=NULL; //删除节点的前面一个节点
    Node *pb=NULL; //要删除的节点
    printf("free: ");
    while (*phead!= NULL) {
        //找到尾节点
        if ((*phead)->p== NULL) { //若链表中仅有一个节点
            printf("%d",(*phead)->i);
            free(*phead);
            *phead=NULL;
        }else{
            //链表中至少有两个以上的节点
            pf=*phead; //链表第一个节点
            pb=pf->p; //链表第二个节点
            while (pb->p !=NULL) {
                pf=pb;
                pb=pb->p;
            }
            printf("%d\n",pb->i);
            free(pb);
            pf->p=NULL;
        }
    }
    printf("\n");
}



//打印节点
void printLink(Node *head)
{
    printf("LinkNode: ");
    while (NULL!=head) {
        printf("%d ",head->i);
        head=head->p;
    }
    printf("\n");
}

//创建无序链表
Node *createlink()
{
    Node * head=NULL; //指向链表第一个节点的指针变量
    Node * end=NULL;  //指向链表最后一个节点的指针变量
    Node * newnode=NULL;//指向新申请的节点的指针变量
    while (1) { 
        newnode=(Node *)malloc(sizeof(Node));//动态申请链表,申请空间
        int num=scanf("%d",&(newnode->i));
        newnode->p=NULL;

        if (0==newnode->i) {
            break;
        }
        if (head==NULL) { //如果head==NULL说明链表为空,新节点是第一个节点也是最后一个节点
            head=end=newnode;
        }else{
            end->p=newnode;//将新节点链接在链表尾部
            end =newnode;   //end指向新链表尾部
        }
        newnode=NULL;
    }
    if (newnode!=NULL) {  //回收最后一个0节点,该节点没有连入链表里
        free(newnode);
    }

    //指向创建完成的链表的首地址
    return head;
}

//创建有序链表
Node *createlinkSort()
{
    Node * head=NULL; //指向链表第一个节点的指针变量
    Node * end=NULL;  //指向链表最后一个节点的指针变量
    Node * newnode=NULL;//指向新申请的节点的指针变量
    while (1) {
        scanf("%d",&num);
        if (num==0) {
            break;
        }
        head=inse(head,i)
    }
    if (newnode!=NULL) {  //回收最后一个0节点,该节点没有连入链表里
        free(newnode);
    }

    //指向创建完成的链表的首地址
    return head;
}

创建顺序表并插入元素

 //创建顺序表并插入元素

#include 
#include 
#define Listsize 100


struct sqlist {
    int data[Listsize];
    int len;
};

//插入元素
void InsertList(struct sqlist *l,int t,int i)
{
    int j;
    if (i<0||i>l->len) {
        printf("position error!");
        exit(1);
    }
    if (l->len>=Listsize) {
        printf("overflow");
        exit(1);
    }
    for (j=l->len-1; j>=i; i--) {
        l->data[j+1]=l->data[j];
    }
    l->data[i]=t;
    l->len++;
}


int main(void)
{
    struct sqlist *sq;
    int i,n,t;
    sq=(struct sqlist *)malloc(sizeof(struct sqlist));//分配空间
    sq->len=0;
    printf("请输入表的长度: \n");
    scanf("%d",&n);
    printf("请输入表的元素:\n");
    for (i=0; iscanf("%d",&t);
        InsertList(sq,t,i);  //插入元素
    }

    printf("插入完成后的表为:\n");
    for (i=0; ilen; i++) {
        printf("%d ",sq->data[i]);
    }
    printf("\n");
    return 0;
}

创建链表并向链表中插入新节点

/*
 创建链表并向链表中插入新节点
 */

#include 
#include 
struct student {
    int num;
    struct student *next;
};
struct student *create(int n);
struct student *insertnode(struct student *head,char x,int i);
struct student *delnode(struct student *head,int i);

int main(void)
{
    int n,i;
    int x;
    struct student *q;  //声明节点类型的指针变量
    printf("输入要创建的节点个数:\n");
    scanf("%d",&n);
    q=create(n);       //创建链表
    printf("输入要插入的节点值:\n");
    scanf("%d",&x);
    printf("输入要插入的位置:\n");
    scanf("%d",&i);
    insertnode(q,x,i);   //插入节点
//    printf("输入要删除的位置:\n");
//    scanf("%d",&i);
//    delnode(q,i);   //删除节点


    printf("输出结果为:\n");
    while (q) {     //输出插入节点后链表
        printf("%d ",q->num);
        q=q->next;
    }
    printf("\n");
    return 0;
}


//创建链表
struct student *create(int n)
{
    int i;
    struct student *head,*p1,*p2;
    int a;
    char b;
    head =  NULL;
    printf("随机输入一段数字: \n");
    for (i=n; i>0; --i) {
        p1=(struct student *)malloc(sizeof(struct student));
        scanf("%d",&a);
        p1->num=a;
        if (head==NULL) {
            head=p1;
            p2=p1;
        }else{
            p2->next=p1;
            p2=p1;
        }
        p2->next=NULL;
    }
    return head;
}


//在链表中新插入节点
struct student *insertnode(struct student *head,char x,int i)
{
    int j=0;
    struct student *p,*s;
    p=head;
    while (p&&j1) {  //找到要插入的位置
        p=p->next;
        ++j;
    }
    if (!p||j>i-1) {
        exit(1);
    }
    s=(struct student *)malloc(sizeof(struct student));//申请节点空间

    s->num=x; //为数据域赋值
    s->next=p->next;
    p->next=s;

}

//删除链表中的节点
struct student *delnode(struct student *head,int i)
{
    int j=0;
    struct student *p,*r;
    p=head;
    while (p&&j1) {  //找到要删除的位置
        p=p->next;
        ++j;
    }
    if (!p||j>i-1) {
        exit(1);
    }
    r=p->next;
    p->next=r->next;   //删除节点
    free(r);
}

从链表中删除节点

/*
 从链表中删除节点
 */

#include 
#include 

typedef struct student
{
    int num;
    struct student *next;
}LNode, *LinkList;

struct student *create(int n);
struct student *delnode(struct student *head,int i);

int main(void)
{
    int n,i;
    int x;
    struct student *q;  //声明节点类型的指针变量
    printf("输入要创建的节点个数:\n");
    scanf("%d",&n);
    q=create(n);       //创建链表
    printf("输入要删除的位置:\n");
    scanf("%d",&i);

    delnode(q,i);   //插入节点
    printf("输出结果为:\n");
    while (q) {     //输出插入节点后链表
        printf("%d ",q->num);
        q=q->next;
    }
    printf("\n");
    return 0;
}


//创建链表
struct student *create(int n)
{
    int i;
    struct student *head,*p1,*p2;
    int a;
    char b;
    head =  NULL;
    printf("随机输入一段数字: \n");
    for (i=n; i>0; --i) {
        p1=(struct student *)malloc(sizeof(struct student));
        scanf("%d",&a);
        p1->num=a;
        if (head==NULL) {
            head=p1;
            p2=p1;
        }else{
            p2->next=p1;
            p2=p1;
        }
        p2->next=NULL;
    }
    return head;
}


struct student *delnode(struct student *head,int i)
{
    int j=0;
    struct student *p,*r;
    p=head;
    while (p&&j1) {  //找到要删除的位置
        p=p->next;
        ++j;
    }
    if (!p||j>i-1) {
        exit(1);
    }
    r=p->next;
    p->next=r->next;  //删除节点
    free(r);
}

你可能感兴趣的:(C语言学习笔记(十三) -链表 Chain)