当前位置:   article > 正文

C语言之常用数据结构_c语言中数据结构有?

c语言中数据结构有?

目录

 

一、顺序表

二、单链表

三、双向链表

三、顺序栈

四、循环队列

五、二叉树


一、顺序表

顺序表是线性表的顺序存储,通过一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。假定线性表的元素类型为ElemType,则线性表的顺序存储类型描述为:

  1. //静态分配
  2. #define MaxSize 50
  3. typedef int ElemType;
  4. typedef struct{
  5. ElemType data[MaxSize];
  6. int length;
  7. }SqList;

C语言中一维数组可以进行动态分配避免溢出;

(1)插入操作

  1. bool ListInsert(SqList &L,int i,ElemType e){
  2. //在顺序表L的第i(1<=i<=L.length+1)个位置插入新元素e
  3. if(i<1 || i>L.length+1)
  4. return false;
  5. if(L.length>=MaxSize)
  6. return false;
  7. for(int j=L.length;j>=i;j--) //将第i个元素及之后的元素后移
  8. L.data[j]=L.data[j-1];
  9. L.data[i-1]=e;
  10. L.length++;
  11. return true;
  12. }

(2)删除操作

  1. bool ListDelete(SqList &L,int i, ElemType &e){
  2. //删除顺序表L中第i个未知的元素
  3. if(i<1 || i>L.length)
  4. return false;
  5. e=L.data[i-1];
  6. for(int j=i;j<L.length;j++)
  7. L.data[j-1]=L.data[j];
  8. L.length--;
  9. return true;
  10. }

(3)按值查找

  1. bool LocateElem(SqList &L,ElemType e){
  2. //查找顺序表中值为e的元素,查找成功则返回元素位置,否则返回0
  3. int i;
  4. for(int i=0;i<L.length;i++)
  5. if(L.data[i]==e)
  6. return i+1;
  7. return 0;
  8. }

 

二、单链表

单链表是线性表的链式存储,通过一组任意的储存单元来存储线性表中的数据元素。为了建立数据元素之间的线性关系,对每个链表节点,除存放元素自身的信息外,还需要存放一个指向其后继的指针。单链表中的节点类型如下:

  1. typedef struct LinkNode{
  2. ElemType data;
  3. struct LinkNode *next;
  4. }LinkNode, *LinkList;

通常用头指针来标识一个单链表,此外为了操作上的方便,在单链表第一个节点之前附加一个结点,称为头结点。

(1)建立单链表

  1. LinkList CreatList1(LinkList &L){
  2. //头插法建立单链表
  3. LNode *s;int x;
  4. L=(LinkList)malloc(sizeof(LNode));
  5. L->next=NULL;
  6. scanf("%d",&x);
  7. while(x!=9999){
  8. s=(LNode*)malloc(sizeof(LNode));
  9. s->data=x;
  10. s->next=L->next;
  11. L->next=s;
  12. scanf("%d",&x);
  13. }
  14. return L;
  15. }
  16. LinkList CreatList2(LinkList &L){
  17. //尾插法建立单链表
  18. int x;
  19. L=(LinkList)malloc(sizeof(LNode));
  20. LNode *s,*r=L;
  21. scanf("%d",&x);
  22. while(x!=9999){
  23. s=(LNode*)malloc(sizeof(LNode));
  24. s->data=x;
  25. r->next=s;
  26. r=s;
  27. scanf("%d",&x);
  28. }
  29. r->next=NULL;
  30. return L;
  31. }

(2)按序号查找节点值

  1. LNode *GetElem(LinkList L,int i){
  2. //取出单链表L(带头节点)中第i个位置的结点指针
  3. int j=1;
  4. LNode *p=L->next;
  5. if(i==0)
  6. return L;
  7. if(i<1)
  8. return NULL;
  9. while(p&&j<i){
  10. p=p->next;
  11. j++;
  12. }
  13. return p;
  14. }

(3)按值查找表结点

  1. LNode *LocateElem(LinkList L,ElemType e){
  2. //查找单链表L(带头结点)中数据值等于e的结点指针,否则返回NULL
  3. LNode *p=L->next;
  4. while(p!=NULL&&p->data!=e)
  5. p=p->next;
  6. return p;
  7. }

(4)插入结点

  1. bool ListFrontInsert(LinkList L,int i,ElemType e){
  2. //将值为x的新节点插入到单链表的第i个位置桑
  3. LinkList p=GetElem(L,i-1);
  4. if(NULL==p){
  5. return false;
  6. }
  7. LinkList s=(LNode*)malloc(sizeof(LNode));
  8. s->data=e;
  9. s->next=p->next;
  10. p->next=s;
  11. return true;
  12. }

三、双向链表

双向链表在单链表的基础上增加了一个指向其前驱的prior指针,结点类型及相关函数描述如下:

  1. typedef int ElemType;
  2. typedef struct DNode{
  3. ElemType data;
  4. struct DNode *prior,*next;
  5. }DNode,*DLinkList;
  6. DLinkList Dlist_head_insert(DLinkList &DL){
  7. //头插法
  8. DNode *s;int x;
  9. DL=(DLinkList)malloc(sizeof(DNode));
  10. DL->next=NULL;
  11. DL->prior=NULL;
  12. scanf("%d",&x);
  13. while(x!=9999){
  14. s=(DNode*)malloc(sizeof(DNode));
  15. s->data=x;
  16. s->next=DL->next;
  17. if(DL->next!=NULL){
  18. DL->next->prior=s;
  19. }
  20. s->prior=DL;
  21. DL->next=s;
  22. scanf("%d",&x);
  23. }
  24. return DL;
  25. }
  26. DLinkList Dlist_tail_insert(DLinkList &DL){
  27. //尾插法
  28. int x;
  29. DL=(DLinkList)malloc(sizeof(DNode));
  30. DNode *s,*r=DL;
  31. DL->prior=NULL;
  32. scanf("%d",&x);
  33. while(x!=9999){
  34. s=(DNode*)malloc(sizeof(DNode));
  35. s->data=x;
  36. r->next=s;
  37. s->prior=r;
  38. r=s;
  39. scanf("%d",&x);
  40. }
  41. r->next=NULL;
  42. return DL;
  43. }
  44. DNode *GetElem(DLinkList DL,int i){
  45. //返回第i个位置的结点指针
  46. int j=1;
  47. DNode *p=DL->next;
  48. if(i==0)
  49. return DL;
  50. if(i<1)
  51. return NULL;
  52. while(p&&j<i){
  53. p=p->next;
  54. j++;
  55. }
  56. return p;
  57. }
  58. bool DListFrontInsert(DLinkList DL,int i,ElemType e){
  59. //插入结点
  60. DLinkList p=GetElem(DL,i-1);
  61. if(NULL==p){
  62. return false;
  63. }
  64. DLinkList s=(DNode*)malloc(sizeof(DNode));
  65. s->data=e;
  66. s->next=p->next;
  67. p->next->prior=s;
  68. s->prior=p;
  69. p->next=s;
  70. return true;
  71. }
  72. bool DListDelete(DLinkList DL,int i){
  73. //删除第i个结点
  74. DLinkList p=GetElem(DL,i-1);
  75. if(NULL==p){
  76. return false;
  77. }
  78. DLinkList q;
  79. q=p->next;
  80. if(q==NULL)
  81. return false;
  82. p->next=q->next;
  83. if(q->next!=NULL){ //删除最后一个元素,需要的判断
  84. q->next->prior=p;
  85. }
  86. free(q);
  87. return true;
  88. }

三、顺序栈

顺序栈是采用顺序存储的栈,它利用一组地址连续的储存单元存放自栈底到栈顶的数据元素,同时设一个指针top指示当前栈顶位置。

  1. //实现栈 可以用数组,也可以用链表
  2. #define MaxSize 50
  3. typedef int ElemType;
  4. typedef struct {
  5. ElemType data[MaxSize];
  6. int top;
  7. }SqStack;
  8. typedef struct LinkNode{
  9. ElemType data;
  10. struct LinkNode *next;
  11. }*LiStack;
  12. void InitStack(SqStack &S){
  13. //初始化
  14. S.top=-1;
  15. }
  16. bool StackEmpty(SqStack &S){
  17. //栈判空
  18. if(S.top==-1)
  19. return true;
  20. else
  21. return false;
  22. }
  23. bool Push(SqStack &S,ElemType x){
  24. //进栈
  25. if(S.top==MaxSize-1){
  26. return false;
  27. }
  28. S.data[++S.top]=x;
  29. return true;
  30. }
  31. bool Pop(SqStack &S,ElemType &x){
  32. //出栈
  33. if(-1==S.top)
  34. return false;
  35. x=S.data[S.top--];
  36. return true;
  37. }
  38. bool GetTop(SqStack &S,ElemType &x){
  39. //读取栈顶元素
  40. if(-1==S.top)
  41. return false;
  42. x=S.data[S.top];
  43. return true;
  44. }

四、循环队列

循环队列是将顺序队列臆造为一个环状空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列。

顺序队列结点类型描述如下:

  1. //队列可以用数组也可用链表实现
  2. #define MaxSize 5
  3. typedef int ElemType;
  4. typedef struct{
  5. ElemType data[MaxSize];
  6. int front,rear;
  7. }SqQueue;
  8. void InitQueue(SqQueue &Q) {
  9. //初始化
  10. Q.rear=Q.front=0;
  11. }
  12. bool isEmpty(SqQueue &Q) {
  13. //判队空
  14. if(Q.rear==Q.front)
  15. return true;
  16. else
  17. return false;
  18. }
  19. bool EnQueue(SqQueue &Q,ElemType x){
  20. //入队
  21. if((Q.rear+1)%MaxSize==Q.front)
  22. return false;
  23. Q.data[Q.rear]=x;
  24. Q.rear=(Q.rear+1)%MaxSize;
  25. return true;
  26. }
  27. bool DeQueue(SqQueue &Q,ElemType &x){
  28. //出队
  29. if(Q.rear==Q.front)
  30. return false;
  31. x=Q.data[Q.front];
  32. Q.front=(Q.front+1)%MaxSize;
  33. return true;
  34. }

链式队列描述如下:

  1. typedef int ElemType;
  2. typedef struct LinkNode{
  3. ElemType data;
  4. struct LinkNode *next;
  5. }LinkNode;
  6. typedef struct{
  7. LinkNode *front,*rear;
  8. }LinkQueue;
  9. void InitQueue(LinkQueue &Q){
  10. //初始化
  11. Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
  12. Q.front->next=NULL;
  13. }
  14. bool IsEmpty(LinkQueue &Q){
  15. //判队空
  16. if(Q.front==Q.rear)
  17. return true;
  18. else
  19. return false;
  20. }
  21. void EnQueue(LinkQueue &Q,ElemType x){
  22. //入队
  23. LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
  24. s->data=x;s->next=NULL;
  25. Q.rear->next=s;
  26. Q.rear=s;
  27. }
  28. bool DeQueue(LinkQueue &Q,ElemType &x){
  29. //出队
  30. if(Q.front==Q.rear) return false;
  31. LinkNode *p=Q.front->next;
  32. x=p->data;
  33. Q.front->next=p->next;
  34. if(Q.rear==p)
  35. Q.rear=Q.front;
  36. free(p);
  37. return true;
  38. }

五、二叉树

  1. //链式存储
  2. typedef struct BiNode
  3. {
  4. char data;
  5. struct BiTNode *lchild,*rchild;
  6. }BiNode,*BiTree;
  7. //前中后序遍历
  8. void Inorder(BiTree T){
  9. if(T == NULL) return ;
  10. Inorder(T->lchild);
  11. // visit(T->data);
  12. printf("%c ", T->data);
  13. Inorder(T->rchild);
  14. }
  15. void preorder(BiTree T){
  16. if(T == NULL) return ;
  17. // visit(T->data);
  18. printf("%c ", T->data);
  19. Inorder(T->lchild);
  20. Inorder(T->rchild);
  21. }
  22. void postorder(BiTree T){
  23. if(T == NULL) return ;
  24. Inorder(T->lchild);
  25. Inorder(T->rchild);
  26. // visit(T->data);
  27. printf("%c ", T->data);
  28. }
  29. //层次遍历
  30. void leverorder(BiTree BT){
  31. InitQueue(Q);
  32. BiTree P;
  33. EnQueue(Q,BT);
  34. while(!IsEmpty(Q){
  35. DeQueue(Q,P);
  36. visit(P);
  37. if(p->lchild!=NULL)
  38. EnQueue(Q,p->lchild);
  39. if(p->rchild!=NULL)
  40. EnQueue(Q,p->rchild);
  41. }
  42. }
  43. }
  44. //非递归
  45. void inorder(BiTree T){
  46. InitStack(S);
  47. BiNode *p = T;
  48. while(!StackEmpty(S) || p){
  49. if(!p) {
  50. Push(S, p);
  51. p = p->lchild;
  52. }else {
  53. Pop(S, p);
  54. printf("%c ", p->data);
  55. p = p->rchild;
  56. }
  57. }
  58. }
  59. void postorder(BiTree T){
  60. InitStack(S);
  61. BiNode *p = T, *last = NULL;
  62. while(!StackEmpty(S) || p){
  63. if(p){
  64. Push(S, p);
  65. p = p->lchild;
  66. }
  67. else {
  68. GetTop(S, p);
  69. if(p->rchild && p == last){ // 向右子树 递归
  70. Pop(S, p);
  71. printf("%c ", p->data);
  72. last = p;
  73. p = NULL;
  74. }else {
  75. p = p->rchild;
  76. }
  77. }
  78. }
  79. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/391764
推荐阅读
相关标签
  

闽ICP备14008679号