簡體   English   中英

雙重鏈接列表問題?

[英]Doubly Linked List Issues?

我已創建,我認為是一個雙重鏈接列表。 這個想法是反轉在新行上輸入的單詞的輸出,所以:

Hello\nAll\n.
.\nAll\nHello

我的想法是遍歷我的列表,直到找到'\\n' ,然后向相反的方向打印,然后返回到我離開的地方,繼續遍歷直到另一條新線,然后再前進並打印等。

但是,我目前的實施似乎無法開始工作,而且我已經碰到了一堵磚牆,並且提示或提示表示贊賞!

typedef struct L { 
char val;
struct L *next;
struct L *prev;
}List;

List *insertList(char val, List *t1 );
List *createList(void);

int main(void) {
  List *z = createList();
  List *pos = z;
  while (pos != NULL) {
    while ( z->val != '\n' ) {
        if (z == NULL)
            break;
            z = z->next;
            pos = z;
}
    while (z != NULL) {
        printf("%c", z->val);
        z = z->prev;
    }
}
return 0;
}
List *createList(void) {
  List *h = NULL;
  char c;
  do { 
    c =(char)getchar();
    h = insertList(c, h);
  }while(c != '.');
  return h;
 }
List *insertList( char val, List *t1) {
  List *t = calloc(1, sizeof( List ));
  t->prev = NULL;
  t->val = val;
  t->next = t1;
    if (t1 != NULL) {
     t1->prev = t;
  }
return t;
}

嘗試使用while循環而不是[編輯注意Chris關於檢查LL結束的評論]:

while (pos != NULL) {
    while (z != NULL) {
        // if you've reached the line feed or the end of the linked list
        if ((z->val == '\n') || (z->next == NULL)) {
            pos = z->next; // store list position just after this char for next time through
            break;
        }
        z = z->next;
    }
    while (z != NULL) {
        printf("%c", z->val);
        z = z->prev;
        // don't print more than just this word!:
        if ((z != NULL) && (z->val == '\n'))
            break;
    }
    // reset z for top inner while loop
    z = pos;
}

基本問題是當外部while循環纏繞時z未被重置; 第二個問題是鏈表的結尾沒有突破第一個內部while循環; 第三個問題是第二個內部,而循環沒有檢查它正在打印的單詞的結尾。

您還需要在結尾處釋放鏈接列表,否則將導致內存泄漏。 您還應檢查calloc()的返回值,以確保它不返回null。

我認為你的結構需要改變,沒有理由有一個雙鏈表來解決你的問題。

你的結構應該包含

struct node {
char *word;
struct node *next;
};

然后你的主循環應該是這樣的:

1) Read character data until delimiter into expandable buffer. Add NULL string terminator.
2) When delimiter is reached create node that points to buffer.
3) Insert NODE at HEAD of list.
4) When '.' is reached print each string starting from head of list.
#include<stdio.h>
#include<conio.h>
#include<malloc.c>
struct dnode{
int data;
struct dnode *prev,*next;
};
typedef struct dnode DNODE;
DNODE *first;
DNODE *last;

DNODE* createDnode(int ele){
DNODE *nnode;
nnode=(DNODE *)malloc(sizeof(DNODE));
nnode->data=ele;
nnode->next=NULL;
nnode->prev=NULL;
return nnode;    

}

//Insert First

DNODE *insertFirst(int ele){
DNODE *nnode;
nnode=createDnode(ele);
if(first==NULL){ //if node is creating first time
    first=last=nnode;
    return;    
}
nnode->prev=NULL;
nnode->next=first;
first=nnode;
return first;
} 

//Insert Last

DNODE *insertLast(int ele){
DNODE *nnode;
nnode=createDnode(ele);
if(first==NULL){ //if node is creating first time
    first=last=nnode;
    return;    
}
last->next=nnode;
nnode->prev=last;
last=nnode;
return last;    
}

 //Insert Before an Element

DNODE *insertBefore(int ele,int key){
DNODE *nnode,*curr,*pre;
nnode=createDnode(ele);
if(first==NULL){ //if node is creating first time
    first=last=nnode;
    return;    
}
if(first->data==key){  // if key is found at first node
    nnode->next=first;
    first=nnode; 
    return first;   
}
curr=first;
while(curr && curr->data!=key){
    pre=curr;
    curr=curr->next;   
}   
if(!curr){   //if search not found then curr will be NULL, it's means the node is added at last
    last->next=nnode;
    nnode->prev=last;
    last=nnode;
    return last;
}
    curr->prev->next=nnode;
    nnode->prev=curr->prev;
    nnode->next=curr;
    curr->prev=nnode;
    return;
  }

 // Insert After an Element

  DNODE *insertAfter(int ele,int key){
  DNODE *nnode,*curr,*pre;
  nnode=createDnode(ele);
  if(first==NULL){ //if node is creating first time
    first=last=nnode;
    return;    
}
curr=first;
while(curr && curr->data!=key){
    //pre=curr;
    curr=curr->next;   
}   
if(!curr){   //if search not found then curr will be NULL, it's means the node        is added at last
    last->next=nnode;
    nnode->prev=last;
    last=nnode;
    return last;
}
nnode->next=curr->next;
curr->next->prev=nnode;
nnode->prev=curr;
curr->next=nnode;
return;    

}

//刪除功能

int removeNode(int key){
DNODE *curr;
if(first==NULL){ //if node is creating first time
    printf("\n\nList is Empty");
    return -1;    
}
curr=first;
if(first->data==key){  //if first node has key
   first=first->next;
   first->prev=NULL;
   curr->next = NULL;
   free(curr);
   return;
}

while(curr && curr->data!=key){
    curr=curr->next;   
} 
if(!curr){   //if search not found then curr will be NULL, 
    return -1;
}

curr->prev->next=curr->next;
curr->next->prev=curr->prev;
curr->next = curr->prev = NULL;
printf("\n\n%d is Successfully Deleted: ",curr->data);
free(curr);
return;
}

void display(){
DNODE *curr;
if(first==NULL)
    printf("\n\nNothing to Display\n\n");
curr=first;
printf("\n\n\tElement in List\n\n\t");
while(curr){
    printf("%d ",curr->data);
    curr=curr->next;    
  }
 }
 main(){
int ele,ch,key;
do{
    printf("\nEnter Your Choice: \n");
    printf("1-Insert First\t2-Insert Last\n3-Insert Before\t4-Insert After\n5-Remove  \t6-Display\n");
    scanf("%d",&ch);
    switch(ch){
        case 1:
            printf("Enter Element To Insert: ");
            scanf("%d",&ele);
            insertFirst(ele);
            break;  
        case 2:
            printf("Enter Element To Insert: ");
            scanf("%d",&ele);
            insertLast(ele);
            break;
         case 3:
            printf("Enter Element To Insert: ");
            scanf("%d",&ele);
            printf("\nEnter Key: ");
            scanf("%d",&key);
            insertBefore(ele,key);
            break;  
        case 4:
            printf("Enter Element To Insert: ");
            scanf("%d",&ele);
            printf("\nEnter Key: ");
            scanf("%d",&key);
            insertAfter(ele,key);
            break; 
        case 5:
            printf("Enter Key to Delete: ");
            fflush(stdin);
            scanf("%d",&key);
            removeNode(key);
            break;
        case 6:
            display();
            break;
    }  
}while(ch!=7);
getch();
return 0;    

}

好的,我有時間看看為什么我的第一個答案不起作用 - 如果你通過調試器運行代碼,那么一些顯而易見的事情。 所以這是一個完全正常的版本。 它可能會進行相當多的優化,但它遵循與原始代碼相同的結構,所以希望您可以遵循它:

typedef struct L { 
    char val;
    struct L *next;
    struct L *prev;
} List;

List* insertList( char val, List *t1 ) {
    List *t = calloc(1, sizeof( List ));
    t->prev = NULL;
    t->val = val;
    t->next = t1;
    if (t1 != NULL)
        t1->prev = t;
    return t;
}

List* createList( void ) {
    List *h = NULL;
    char c;

    do {
        c =(char)getchar();
        h = insertList( c, h );
    } while (c != '.');

    return h;
}

void freeList( List *list ) {
    // free the linked list
    if (list != NULL) {
        freeList( list->next );
        free( list );
    }
}

int main( void ) {
    // create list
    List *head = createList();
    List *pos = head, *currentChar = NULL, *wordStart = NULL;

    while (pos != NULL)
    {
        // find next word
        wordStart = NULL;
        while (pos != NULL)
        {
            // gone past the beginning of a word yet?
            if ((pos->val == '\n') || (pos->next == NULL)) 
            {
                wordStart = (pos->next == NULL) ? pos : pos->prev; // note where this word starts
                pos = pos->next; // jump over \n, or go to end of list (null), for next time into this loop
                break; // jump out of this loop so we can output the word
            }
            else // not found end of word yet - on to next char
                pos = pos->next;
        }

        // have we found a word? if so, output it!
        if (wordStart != NULL)
        {
            currentChar = wordStart; // start at first char in the word
            while (currentChar != NULL)
            {
                printf( "%c", currentChar->val ); // output this char
                currentChar = currentChar->prev; // on to next char in the word
                if ((currentChar != NULL) && (currentChar->val == '\n')) 
                    break; // stop after last char of the word
            }
            // print the line-feed just before wordStart (if there is one)
            if (wordStart->next != NULL)
                printf( "%c", wordStart->next->val );
        }
        else // we've reached the end - stop
            break; // not really necessary - pos should be NULL at this point anyway
    }

    freeList( head ); // free linked list memory

    return 0;
}

主要的變化是我輸出換行的方式。 我意識到這不是你需要的每個單詞之后的換行符,而是它之前的那個單詞(完全不符合邏輯 - 我想知道這個問題原來是什么意思?)。 但它現在輸出你所需要的。 我已經添加了一個函數來為你釋放鏈表內存。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM