链表 的增删改查

单链表 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Student
{
    int num ;
    struct Student * next ;    
}Student;

Student *CreateList(Student *stu , int num )
{
     Student *head = NULL , *ptemp = NULL , *qnew = NULL;
    printf("是否创建链表?   [y/n]") ;
    char cmd = getchar() ;
    while(getchar()!='\n');
    int flag = num ;
    if(cmd == 'y')
    {
          printf("创建中...\n") ;
        while(flag --)
        {
              qnew = (Student *)malloc(sizeof(Student)) ;
            if(NULL == qnew)
            {
              printf("创建链表失败!") ;
              break ;
            }
            qnew->num = stu[num - flag - 1].num ;
            qnew->next = NULL ;
            if(NULL == head)
            {
                head = qnew ;
            //    ptemp = head ;
            }else
            {
                  qnew->next = head ;
                head = qnew ;
              /*
                ptemp->next = qnew ;
                ptemp = qnew ;
                */
            }
        }
        printf("创建完成!\n") ;
    }else{
        printf("退出创建链表") ;
    }
    return head ;
}

int getListlength(Student *head)
{
    int index = 0 ;
    if(NULL == head)
          index = 0 ;
    else{
        while(NULL != head)
        {    
              index++ ;
            head = head->next ;
        }
    }

    printf("链表长度为%d\n",index) ;
    return index ;
}
Student * searchListIndex(Student *head , int index)
{
    if(NULL == head)
    { 
          printf("原链表为空链表!") ; 
        return NULL;
    }
    if(index <= 0||index >getListlength(head) )
    {
        printf("parm error! [%s,%d]\n",__FILE__ ,__LINE__);
        return NULL;
    }
    while(--index)
    {
        head=head->next ;
    }
    return head ;
}
/**
 *
 */
void Showlist(Student *head)
{
      int index = 0 ;
      printf("打印链表:\n") ;
    if(NULL == head)
    {
        printf("空链表!") ;
    }else
    {
          Student *p = head ; 
        while(p!=NULL)
        {
              index++ ;
            printf("[%d|%p]-->",p->num,p) ;
            p = p->next ;
            putchar(10) ;

        }

    }
    putchar(10) ;
}
//释放链表
void freeList(Student *head)
{
      printf("释放链表!\n") ;
    
    if(head != NULL)
    {
          Student *p = head ,*q = head ;
        while(NULL!= q)
        {
             p = q->next ;
              free(q) ;
            q = p ;
        }
    }
    printf("释放完成!\n") ;
}
Student * insertList(Student *head,int data , int index)
{
      int len = getListlength(head) ;
    if(index < 1 || index > len + 1)
    {
        printf("parm error [%s,%d]",__FILE__,__LINE__) ;
        return head ;
    }
            Student *pnew = (Student*)malloc(sizeof(Student)) ;
            assert(pnew!=NULL) ;
            pnew -> num = data ;
            pnew ->next = NULL ;
    if(1 == index)
    {
        printf("头插入\n") ;
        pnew ->next =head ;
        head  =pnew ;
    }else 
    {
          printf("末尾插入\n") ;
          Student *p = searchListIndex(head , index-1) ;
        pnew -> next = p ->next ;
        p -> next = pnew ;
    }
    return head ;

}
Student * deleteList(Student *head , int index)
{
    if(NULL == head)
    {
        printf("parm error![%d]\n",__LINE__) ;
        return head ;
    }
    int len = getListlength(head) ; 
    if(index < 1 || index > len)
    {
        printf("parm error!\n") ;
    }
    if(1 == index)
    {
      printf("删除头部\n") ;
        Student *del = head ;
        head = head -> next ;
        free(del) ;
    }else
    {
        Student *predel = searchListIndex(head , index -1) ;
        Student *del = predel -> next ;
        predel -> next = del -> next ;
        free(del) ;
    }
    return head ;
}
int main()
{
    Student *head = NULL;
    Student stu[9] ;
    for(int i =0 ; i<9 ;++i)
    {
        stu[i].num = i ;
        stu[i].next = NULL ;
    }
    head = CreateList(stu , 9) ;
    Showlist(head) ;
    Student *pindex = searchListIndex(head , 3) ;
    if(NULL == pindex)
    {
        printf("无指定节点!\n") ;
    }else
    {
        printf("index = %d , Node = [%d|%p]\n",3 , pindex->num , pindex) ;
    }
    deleteList(head ,9) ;
    Showlist(head) ;
    Student *pinsert = insertList(head , 12,9) ;
    Showlist(pinsert) ;
    freeList(head) ;
      printf("Hello  Link\n");
    return 0 ;
}
 

双链表 

  • 插入不向单链表只需考虑是否是头插 。需要考虑4种情况: 空链表、头插、中间插、尾插。
  • 删除需要考虑: 空链表、 头删、尾删 、中间删、只有一个结点。需要考虑5种情况。

#include "./Dnode.h"
#include <stdio.h>
#include <stdlib.h>
dnode * createDoubleLink()
{
    printf("你想创建几个结点\n") ;
    int num , flag;
    scanf("%d", &num) ; while(getchar()!='\n');
    dnode *pnew = NULL ;

    dnode *head = NULL ;

    dnode *ptemp = NULL ;

    flag = num ;
    int data ;
    while(num--)
    {
        printf("请输入第%d个结点数据:\t\n",flag - num) ;
        scanf("%d",&data) ; 
        while(getchar()!='\n') ;
        pnew = (dnode*)malloc(sizeof(dnode)) ;
        pnew -> pre = NULL ;
        pnew -> next = NULL ;
        pnew -> data = data ;

        if(NULL == head)
        {
            head = pnew ;
            ptemp = head ;
        }else
        {
            ptemp -> next = pnew ;
            pnew -> pre = ptemp ;
            ptemp = pnew ;
        }
    }
    return head ;


int getLinkLen(dnode * head)
{
      int len = 0 ;
    while(head)
    {
        len++ ;
        head = head -> next ;
    }
    return len ;
}

void showLink(dnode *head)
{
    if(NULL == head)
    {
        printf("链表为空\n") ;
        return ;
    }
    printf("链表数据为:\n") ;
    while(head)
    {
        printf("[%15p | %3d | %15p]-->\n",head->pre,head->data , head->next) ;
        head = head->next ;
    }
    putchar(10) ;

}

dnode * getNodeAtIndex(dnode * head , int index) 
{
    int flag = index ;
    while(--flag)
    {
        head = head -> next ;
    }
    return head ;
}

dnode * insertLink(dnode * head , int data , int index) 
{
      int len = getLinkLen(head) ;
    //入参检查
    if(index < 1 || index > len)
    {
        printf("parm error [%s|%d]\n",__FILE__,__LINE__) ;
        return head ;
    }
    dnode *pretemp = NULL;
    dnode *pnew = (dnode*)malloc(sizeof(dnode)) ;
    pnew -> pre = NULL ;
    pnew -> next = NULL ; 
    pnew -> data = data ;
    if(1 == index)
    {
        //1,空链表
        if(NULL == head)
        {
            head = pnew ;
        }
        //2,非空链表,头插入
        else
        {
            pnew ->next = head ;
            head -> pre = pnew ;
            head = pnew ;
        }
    }else if(index > 1 && index < len ) //中间插入
    {
        pretemp = getNodeAtIndex(head , index) ;
        pretemp -> pre -> next = pnew ;
        pnew -> next = pretemp ;
        pnew -> pre = pretemo -> pre ;
        pretemp -> pre = pnew ;
    }else if(index == len)    //尾插入
    {
        pretemp = getNodeAtIndex(head, len) ;
        pretemp -> next = pnew ;
        pnew -> pre = pretemp ;
    }
    return head ;
    
}

dnode * findMax(dnode *head) 
{
    dnode * pmax = head ;
    while(NULL!=head)
    {
        if(head->data > pmax->data)
        {
            pmax = head ;
        }
    }

//排序
dnode * sortLink(dnode * head) 
{
    if(NULL == head)
    {
          printf("为空\n") ;
        return head ;
    }
    dnode *p =NULL ;
    dnode *q =NULL ;
    while(NULL != head)
    {
        p = findMax(head) ;
        head = moveMax(head, p) ;
        if(NULL == q)
        {
            p -> next = q ;
            q = p ;
        }else
        {
            p -> next = q ;
            q -> pre = p ;
            q = p ;
        }
    }
    return q ;
}
 

 

Hash表 开放地址法

 

#include <stdio.h>
#include <stdlib.h>
#define LEN 11
void inithash(int hash[])
{
    for(int i=0 ;i<LEN ;++i)
    {
        hash[i] = 0 ;
    }
}

int HashFun(int key)
{
    return key%LEN ;
}

int HashInsert(int hash[] ,int data)
{
    int index , newIndex ;
    index = HashFun(data) ;
    if(hash[index] == 0)
    {
        hash[index] = data ;
        return 0;
    }else
    {
        for(int i=1 ; i<LEN ;++i)
        {
            if(hash[index+1]==0)
            {
                hash[index+1] = data ;
                return 0;
            }
        }
        return -1 ;
    }
}

void showHash(int hash[])
{
    for(int i=0;i<LEN ;++ i)
    {
        printf("hash[%d] = %d \n",i , hash[i]) ;
    }
}
int main()
{
      int hash[11] ;
    inithash(hash) ;
    HashInsert(hash,20) ;
    HashInsert(hash,30) ;
    HashInsert(hash,70) ;
    HashInsert(hash,15) ;
    HashInsert(hash,8) ;
    HashInsert(hash,12) ;
    HashInsert(hash,18) ;
    HashInsert(hash,63) ;
    HashInsert(hash,19) ;
    showHash(hash) ;
    return 0 ;
}
 

Hash 链地址法

#include <stdio.h>
#include <stdlib.h>
#define LEN 11
#include <assert.h>

typedef struct node
{
    int data ;
    struct node *next ;
}node ;

void HashLinkInit(node *hash[])
{
  for(int i=0 ;i<LEN;++i)
  {
    hash[i] = NULL ;
  }
}

int HashLinkFun(int key)
{
    return key%LEN ;
}

int HashLinkInsert(node * hash[] ,int data)
{
    int index = HashLinkFun(data) ;
    node * pnew = (node*) malloc(sizeof(node)) ;
    node * p = hash[index]  ;
    assert(pnew!=NULL) ;
    pnew ->data = data ;
    pnew ->next =NULL ;
    if(NULL == hash[index])
    {
        hash[index] = pnew ;
        return 0 ;
    }else
    {
        while(p->next != NULL)
        {
            p = p->next ;
        }
        p->next = pnew ;
        return 0 ;
    }
    return -1;
}

void showHashLink(node *hash[])
{
    for(int i=0 ; i<LEN ;++i)
    {
        node *p = hash[i] ;
        if(NULL == p)
            printf("第%d条链表没有任何数据\n",i) ;
        else
        {
            while(p)
            {
                printf("第%d条链表 : data = %d\n",i,p->data) ;
                p = p->next ;
            }
        }
    }
}

int main()
{
  node * hash[LEN] ;
  HashLinkInit(hash) ;
  HashLinkInsert(hash , 20) ;
  HashLinkInsert(hash , 30) ;
  HashLinkInsert(hash , 70) ;
  HashLinkInsert(hash , 15) ;
  HashLinkInsert(hash , 8) ;
  HashLinkInsert(hash , 12) ;
  HashLinkInsert(hash , 18) ;
  HashLinkInsert(hash , 63) ;
  HashLinkInsert(hash , 19) ;
  showHashLink(hash) ;
  return 0;
}
 

二叉树

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef struct BTree
{
    int data ;
    struct BTree * left ;
    struct BTree * right ;
}btree ;

btree *createBTree()
{
      btree * root = NULL ;
    btree * pnew = NULL ;
    int data ;
    printf("输入结点数据\n") ;
    scanf("%d",&data );
    while(getchar()!='\n') ;
    while(data)
    {
        pnew = (btree *)malloc(sizeof(btree)) ;
        assert(pnew!=NULL) ;
        pnew -> data = data ;
        pnew -> left = NULL ;
        pnew -> right = NULL ;
        
        if(NULL == root)
        {
            root = pnew ;
        }else
        {
            btree *p = root ,*q = NULL ;
            while(NULL != p)
            {
                q = p ;
                if( p -> data > data )
                {
                    p = p -> left ;
                }else
                {
                    p = p -> right ;
                }
            }    
            if( q -> data > data)
            {
                q -> left = pnew ;
            }else
            {
                q -> right = pnew ;
            }
        }
        printf("请输入下一节点的数据\n") ;
        scanf("%d",&data) ;
        while(getchar()!='\n') ;
    }
    return root ;
}
//先序递归遍历
void showDiguiPre(btree * root)
{
    if(NULL!=root)
    {
        printf("data = %d\n",root->data) ;
        showDiguiPre(root->left) ;
        showDiguiPre(root->right) ;
    }
}

//先序非递归遍历
void showOrderByPre(btree *root)
{
    if(NULL == root)
    {
        printf("二叉树为空\n") ;
        return  ;
    }
    btree *stack[100] ;
    int top = -1 ;
    btree * p;
    stack[++top] = root ;
    while(top != -1)
    {
        p = stack[top--] ;
        printf("data = %d\n",p->data) ;
        if(NULL != p->right)
          stack[++top] = p->right ;
        if(NULL !=p->left)
          stack[++top] = p->left ;
    }
}

//中序非递归遍历
void showOrderByInter(btree * root)
{
    if(NULL == root)
    {
        printf("二叉树为空\n") ;
        return ;
    }

    btree * stack [100] ;
    int top = -1 ;
    btree * p = root ;
    while(-1 != top || NULL != p)
    {
        while(NULL != p)
        {
            stack[++top] = p ;
            p = p->left ;
        }
        if(-1 != top )
        {
              p = stack[top--] ;
            printf("data = %d\n",p->data) ;
            p = p->right ;
        }
    }
}
//后序非递归遍历
void showOrderByPost(btree * root)
{
      if(NULL == root)
      return ;
    btree * stack1[100] ;
    btree * stack2[100] ;
    int top1 = -1 ;
    int top2 = -1 ;
    btree * p =NULL ;
    stack1[++top1] = root ;
    while(-1 != top1)
    {
        p = stack1[top1--] ;
        stack2[++top2] = p ;
        if(NULL != p->left)
            stack1[++top1] = p->left ;
        if(NULL != p->right)
            stack1[++top1] = p->right ;
        
    }
    while(-1 != top2)
    {
        p = stack2[top2--] ;
        printf("data = %d\n",p->data) ;
    }
}
//递归中序
void showDiguiInter(btree * root)
{
    if(NULL != root)
    {
          showDiguiInter( root -> left );
        printf("data = %d\n",root->data) ;
        showDiguiInter(root -> right );
    }
}
//递归后序
void showDiguiPost(btree * root)
{
    if(NULL != root)
    {
        showDiguiPost(root -> left );
        showDiguiPost( root -> right) ;
        printf("data = %d\n",root ->data) ;
    }
}
/*
//层次遍历
void showLevel(btree *root)
{
    if(NULL != root)
    {
        printf("链表为空\n");
        return ;
    }
    btree *que[100] ;
    int front ,rear ;
    front = rear = 0;
    btree *q = NULL ;
    rear = (rear+1)%100 ;
}
*/
int main()
{
      btree * root = createBTree() ;
    printf("先序非递归遍历\n") ;
    showOrderByPre(root) ;
    printf("先序递归遍历\n") ;
    showDiguiPre(root) ;
    printf("中序递归遍历\n") ;
    showDiguiInter(root) ;
    printf("中序非递归遍历\n") ;
    showOrderByInter(root) ;
    printf("后序递归遍历\n") ;
    showDiguiPost(root) ;
    printf("后序非递归遍历\n") ;
    showOrderByPost(root) ;
    return 0 ;
}

半十字链表 

好的,我可以为您介绍一下 C 语言中动态链表增删改查操作。 首先,我们需要定义一个链表结构体: ```c typedef struct Node { int data; struct Node *next; } Node, *LinkedList; ``` 其中,`data` 表示链表节点中存储的数据,`next` 表示指向下一个节点的指针。 接下来,我们可以实现链表的创建操作: ```c LinkedList createList() { LinkedList head = (LinkedList)malloc(sizeof(Node)); head->next = NULL; return head; } ``` 这个函数会返回一个链表头节点的指针,也就是一个空链表。 接下来,我们可以实现链表节点的插入操作: ```c void insertNode(LinkedList L, int data) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = data; newNode->next = L->next; L->next = newNode; } ``` 这个函数会在链表头节点后插入一个新的节点。 接下来,我们可以实现链表节点的删除操作: ```c void deleteNode(LinkedList L, int data) { Node *p = L; while (p->next != NULL && p->next->data != data) { p = p->next; } if (p->next == NULL) { printf("Not found!\n"); return; } Node *tmp = p->next; p->next = tmp->next; free(tmp); } ``` 这个函数会在链表中查找指定数据的节点,并删除它。 最后,我们可以实现链表节点的查找操作: ```c Node *findNode(LinkedList L, int data) { Node *p = L->next; while (p != NULL && p->data != data) { p = p->next; } return p; } ``` 这个函数会在链表中查找指定数据的节点,并返回它的指针。 以上就是 C 语言中动态链表增删改查操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值